gibbon 3.0.1 → 3.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3cadf43e229868a253bae8af2b7e609db5ffd11b
4
- data.tar.gz: 95049f9c9ce5f1d3b9cde18f4650d5be52b13947
2
+ SHA256:
3
+ metadata.gz: 9948496f6f0ccccd5c2796b5d6ad2e1c656e3fd4db624bbb36a24e81d9161be7
4
+ data.tar.gz: 16ae83c4ec4af77425a9534b0c8c037fde234e694f21e77aa3572cad035867b4
5
5
  SHA512:
6
- metadata.gz: 58ab02cdd0ebd1cff4c0211b3a6674484db6a50b52aa34dc7efc746e1c75792dca7a4dedd58e8efc7e38fef73fc285f4859c809bba1f1b5cf1d674bc89cca436
7
- data.tar.gz: 15459d6835355d637505ffc34c3aecbac0a6232a271d1481952c60028f30bd7264c35bd5e922d12ec12717b36a83df59046c808f43b02c19dda60d9f60f2f33f
6
+ metadata.gz: 6e68e1c2b1e77f738e48a6a7256fb35c0904ae1d7f487daaeccd9b65cfc98ab57d3244f5f3fa1e699cd424fbaf36561ae83d3891f02029317595831c031c65d0
7
+ data.tar.gz: 443c2f49c096106061887b29d052d05064a23b508740da354aea4f49bbed3201366c9a548155da051664906fc40b39e4bf9611571707db82bcb542859e7402c2
@@ -1,8 +1,11 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  cache: bundler
4
+ before_install:
5
+ - gem install bundler # -v 1.7.14 if a specific version is needed
4
6
  rvm:
5
- - 2.0.0
6
7
  - 2.1.5
7
8
  - 2.2.2
8
- - 2.3.3
9
+ - 2.3.8
10
+ - 2.4.5
11
+ - 2.5.3
@@ -1,5 +1,25 @@
1
1
  ## [Unreleased][unreleased]
2
2
 
3
+ ## [3.2.1] - 2019-10-02
4
+ - Fixed compatibility with Faraday 0.16.2+
5
+ - Set minimum Ruby to 2.3.8
6
+
7
+ ## [3.2.1] - 2017-11-08
8
+ - Set minimum Ruby to 2.1
9
+
10
+ ## [3.2.0] - 2017-11-08
11
+ - Force TLS version 1.2
12
+
13
+ ## [3.1.1] - 2017-09-25
14
+ - Fix MailChimpError initialization
15
+
16
+ ## [3.1.0] - 2017-07-27
17
+ - Add back support for Export API until MailChimp stops supporting it
18
+ - Implement `responds_to_missing`
19
+
20
+ ## [3.0.2] - 2017-05-08
21
+ - Fix subtle bug in `symbolize_keys` when parsing error
22
+
3
23
  ## [3.0.1] - 2017-01-13
4
24
  - Gibbon::Request (API 3.0) now returns a `Gibbon::Response` object that exposes `headers` and the parsed response `body`
5
25
  - Remove Export API support (this is deprected after all)
@@ -66,7 +86,9 @@
66
86
  ## [1.1.4] - 2012-11-04
67
87
  - Fix JSON::ParserError on export calls that return blank results
68
88
 
69
- [unreleased]: https://github.com/amro/gibbon/compare/v3.0.1...HEAD
89
+ [unreleased]: https://github.com/amro/gibbon/compare/v3.1.0...HEAD
90
+ [3.1.0]: https://github.com/amro/gibbon/compare/v3.0.2...v3.1.0
91
+ [3.0.2]: https://github.com/amro/gibbon/compare/v3.0.1...v3.0.2
70
92
  [3.0.1]: https://github.com/amro/gibbon/compare/v3.0.0...v3.0.1
71
93
  [3.0.0]: https://github.com/amro/gibbon/compare/v2.2.5...v3.0.0
72
94
  [2.2.5]: https://github.com/amro/gibbon/compare/v2.2.4...v2.2.5
@@ -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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2015 Amro Mousa
1
+ Copyright (c) 2010-2017 Amro Mousa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -3,22 +3,22 @@
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
- ##Important Notes
6
+
7
+ ## Important Notes
8
8
 
9
9
  Please read MailChimp's [Getting Started Guide](http://kb.mailchimp.com/api/article/api-3-overview).
10
10
 
11
11
  Gibbon 3.0.0+ returns a `Gibbon::Response` instead of the response body directly. `Gibbon::Response` exposes the parsed response `body` and `headers`.
12
12
 
13
- ##Installation
13
+ ## Installation
14
14
 
15
15
  $ gem install gibbon
16
16
 
17
- ##Requirements
17
+ ## Requirements
18
18
 
19
19
  A MailChimp account and API key. You can see your API keys [here](http://admin.mailchimp.com/account/api).
20
20
 
21
- ##Usage
21
+ ## Usage
22
22
 
23
23
  First, create a *one-time use instance* of `Gibbon::Request`:
24
24
 
@@ -26,7 +26,7 @@ First, create a *one-time use instance* of `Gibbon::Request`:
26
26
  gibbon = Gibbon::Request.new(api_key: "your_api_key")
27
27
  ```
28
28
 
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 an resets the path.
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.
30
30
 
31
31
  You can set an individual request's `timeout` and `open_timeout` like this:
32
32
 
@@ -84,7 +84,7 @@ gibbon = Gibbon::Request.new(api_key: "your_api_key", symbolize_keys: true)
84
84
 
85
85
  MailChimp's [resource documentation](http://kb.mailchimp.com/api/resources) is a list of available resources.
86
86
 
87
- ##Debug Logging
87
+ ## Debug Logging
88
88
 
89
89
  Pass `debug: true` to enable debug logging to STDOUT.
90
90
 
@@ -110,7 +110,7 @@ Gibbon::Request.logger = MyLogger.new
110
110
 
111
111
  ### Lists
112
112
 
113
- Fetch all lists:
113
+ Fetch first page of lists:
114
114
 
115
115
  ```ruby
116
116
  gibbon.lists.retrieve
@@ -130,7 +130,7 @@ gibbon.lists(list_id).members.retrieve
130
130
 
131
131
  ### Subscribers
132
132
 
133
- Get all subscribers for a list:
133
+ Get first page of subscribers for a list:
134
134
 
135
135
  ```ruby
136
136
  gibbon.lists(list_id).members.retrieve
@@ -178,6 +178,21 @@ Get a specific member's information (open/click rates etc.) from MailChimp:
178
178
  gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).retrieve
179
179
  ```
180
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
+
181
196
  ### Batch Operations
182
197
 
183
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.
@@ -236,7 +251,7 @@ gibbon.lists(list_id).members.retrieve(params: {"fields": "members.email_address
236
251
 
237
252
  ### Campaigns
238
253
 
239
- Get all campaigns:
254
+ Get first page of campaigns:
240
255
 
241
256
  ```ruby
242
257
  campaigns = gibbon.campaigns.retrieve
@@ -457,6 +472,33 @@ Gibbon 2.x+:
457
472
  ```ruby
458
473
  gibbon.lists(list_id).members.create(body: {email_address: "foo@bar.com", status: "subscribed", merge_fields: {FNAME: "Bob", LNAME: "Smith"}})
459
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.
460
502
 
461
503
  ## Thanks
462
504
 
@@ -464,5 +506,5 @@ Thanks to everyone who has [contributed](https://github.com/amro/gibbon/contribu
464
506
 
465
507
  ## Copyright
466
508
 
467
- * Copyright (c) 2010-2017 Amro Mousa. See LICENSE.txt for details.
468
- * MailChimp (c) 2001-2017 The Rocket Science Group.
509
+ * Copyright (c) 2010-2018 Amro Mousa. See LICENSE.txt for details.
510
+ * MailChimp (c) 2001-2018 The Rocket Science Group.
@@ -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.0.0'
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')
@@ -9,6 +9,7 @@ require 'gibbon/mailchimp_error'
9
9
  require 'gibbon/request'
10
10
  require 'gibbon/api_request'
11
11
  require 'gibbon/response'
12
+ require 'gibbon/export'
12
13
 
13
14
  module Gibbon
14
15
  end
@@ -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
- if error.is_a?(Faraday::Error::ClientError) && error.response
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
 
@@ -117,8 +120,12 @@ module Gibbon
117
120
 
118
121
  if parsed_response
119
122
  error_params[:body] = parsed_response
120
- error_params[:title] = parsed_response["title"] if parsed_response["title"]
121
- error_params[:detail] = parsed_response["detail"] if parsed_response["detail"]
123
+
124
+ title_key = symbolize_keys ? :title : "title"
125
+ detail_key = symbolize_keys ? :detail : "detail"
126
+
127
+ error_params[:title] = parsed_response[title_key] if parsed_response[title_key]
128
+ error_params[:detail] = parsed_response[detail_key] if parsed_response[detail_key]
122
129
  end
123
130
 
124
131
  end
@@ -142,7 +149,7 @@ module Gibbon
142
149
  end
143
150
 
144
151
  def rest_client
145
- 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|
146
153
  faraday.response :raise_error
147
154
  faraday.adapter adapter
148
155
  if @request_builder.debug
@@ -153,7 +160,7 @@ module Gibbon
153
160
  client
154
161
  end
155
162
 
156
- def parse_response(response)
163
+ def parse_response(response)
157
164
  parsed_response = nil
158
165
 
159
166
  if response.body && !response.body.empty?
@@ -162,9 +169,8 @@ module Gibbon
162
169
  body = MultiJson.load(response.body, symbolize_keys: symbolize_keys)
163
170
  parsed_response = Response.new(headers: headers, body: body)
164
171
  rescue MultiJson::ParseError
165
- error = MailChimpError.new("Unparseable response: #{response.body}")
166
- error.title = "UNPARSEABLE_RESPONSE"
167
- error.status_code = 500
172
+ error_params = { title: "UNPARSEABLE_RESPONSE", status_code: 500 }
173
+ error = MailChimpError.new("Unparseable response: #{response.body}", error_params)
168
174
  raise error
169
175
  end
170
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Gibbon
2
- VERSION = "3.0.1"
3
- end
2
+ VERSION = "3.3.0"
3
+ end
@@ -9,38 +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
- it "surfaces client request exceptions as a Gibbon::MailChimpError" do
13
- exception = Faraday::Error::ClientError.new("the server responded with status 503")
14
- stub_request(:get, "#{@api_root}/lists").to_raise(exception)
15
- expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
16
- 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
17
18
 
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
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
24
25
 
25
- it "surfaces an unparseable response body as a Gibbon::MailChimpError" do
26
- response_values = {:status => 503, :headers => {}, :body => '[foo]'}
27
- exception = Faraday::Error::ClientError.new("the server responded with status 503", response_values)
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)
28
29
 
29
- stub_request(:get, "#{@api_root}/lists").to_raise(exception)
30
- expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
31
- end
30
+ stub_request(:get, "#{@api_root}/lists").to_raise(exception)
31
+ expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
32
+ end
33
+
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)
39
+ begin
40
+ api_request.send :handle_error, exception
41
+ rescue => boom
42
+ expect(boom.status_code).to eq 503
43
+ expect(boom.raw_body).to eq "A non JSON response"
44
+ end
45
+ end
32
46
 
33
- context "handle_error" do
34
- it "includes status and raw body even when json can't be parsed" do
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"
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
58
+ end
43
59
  end
44
60
  end
45
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
46
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
@@ -73,7 +73,7 @@ describe Gibbon do
73
73
  expect(@gibbon.proxy).to be_nil
74
74
  end
75
75
 
76
- it "sets an proxy url key from the 'MAILCHIMP_PROXY_URL' ENV variable" do
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.0.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amro Mousa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-14 00:00:00.000000000 Z
11
+ date: 2019-10-02 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.0.0
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
- rubyforge_project: gibbon
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