gibbon 3.5.0 → 4.0.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/.travis.yml +18 -8
- data/CHANGELOG.md +6 -1
- data/Gemfile +0 -8
- data/README.markdown +10 -10
- data/gibbon.gemspec +3 -4
- data/lib/gibbon/api_request.rb +5 -1
- data/lib/gibbon/version.rb +1 -1
- data/spec/gibbon/api_request_spec.rb +129 -0
- data/spec/gibbon/gibbon_helpers_spec.rb +27 -0
- data/spec/gibbon/mailchimp_error_spec.rb +18 -0
- data/spec/gibbon/request_spec.rb +141 -0
- data/spec/gibbon/response_spec.rb +17 -0
- metadata +13 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1cb1352737a9335535ba7d79420ec208817700b6e8b4fcf07a449499837b721f
|
|
4
|
+
data.tar.gz: 5fd15b6c055607e95a2e81f8b4fda95b606dc6be3ac7aa147057acd13c946a1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20bd382a94c31402452f63037c0f266cdb291493b72b93b1aab2c15021fb108fbf9a45b4ced1f3070c2c2a18aaee3bd117ef98dc4b8846b3a07f44ac042c864f
|
|
7
|
+
data.tar.gz: a030570ce92ecd7744ee1ed8dead15f0a176e3b178fd0b410e4c11a870f90ebbc0ba5909a82ae59b55959cf1ae3c06f0fd612826b5fdf93a26954907aba96729
|
data/.travis.yml
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
-
sudo: false
|
|
3
2
|
cache: bundler
|
|
4
|
-
before_install:
|
|
5
|
-
- gem install bundler # -v 1.7.14 if a specific version is needed
|
|
6
3
|
rvm:
|
|
7
|
-
- 2.4.5
|
|
8
|
-
- 2.5.7
|
|
9
|
-
- 2.6.5
|
|
10
|
-
- 2.7
|
|
11
|
-
- 3.0.0
|
|
12
4
|
- 3.1
|
|
13
5
|
- 3.2
|
|
6
|
+
- 3.3
|
|
7
|
+
- 3.4
|
|
8
|
+
jobs:
|
|
9
|
+
include:
|
|
10
|
+
# rvm's stable release does not know Ruby 4.0 yet, so boot on 3.4,
|
|
11
|
+
# then upgrade rvm to master and install 4.0 from there
|
|
12
|
+
- name: "4.0 (via rvm master)"
|
|
13
|
+
rvm: 3.4
|
|
14
|
+
before_install:
|
|
15
|
+
- rvm get master
|
|
16
|
+
- rvm install ruby-4.0
|
|
17
|
+
- rvm use ruby-4.0
|
|
18
|
+
- ruby -v
|
|
19
|
+
# Bundler 4 (shipped with Ruby 4.0) removed the --path flag that
|
|
20
|
+
# Travis's default install step still passes
|
|
21
|
+
install:
|
|
22
|
+
- bundle config set --local path vendor/bundle
|
|
23
|
+
- bundle install --jobs=3 --retry=3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [4.0.0] - 2026-07-23
|
|
2
|
+
- Require Ruby 3.1+ (drops support for EOL Rubies 2.4 through 3.0)
|
|
3
|
+
- Require TLS 1.2 as a minimum instead of pinning it exactly, allowing TLS 1.3
|
|
4
|
+
- Modernize development setup: loosen rspec pin, remove Rubinius leftovers, update CI matrix to Ruby 3.1 through 4.0
|
|
5
|
+
|
|
6
|
+
## [3.5.0] - 2023-06-07
|
|
2
7
|
- Remove support for retired Export API
|
|
3
8
|
|
|
4
9
|
## [3.4.4] - 2022-02-24
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# gibbon
|
|
2
2
|
|
|
3
|
-
Gibbon is an API wrapper for MailChimp's [API](
|
|
3
|
+
Gibbon is an API wrapper for MailChimp's [API](https://mailchimp.com/developer/marketing/api/).
|
|
4
4
|
|
|
5
|
-
[](https://app.travis-ci.com/github/amro/gibbon)
|
|
5
|
+
[](https://app.travis-ci.com/github/amro/gibbon)
|
|
6
6
|
|
|
7
7
|
## Important Notes
|
|
8
8
|
|
|
9
|
-
Please read MailChimp's [Getting Started Guide](
|
|
9
|
+
Please read MailChimp's [Getting Started Guide](https://mailchimp.com/developer/marketing/guides/quick-start/).
|
|
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
|
|
|
@@ -16,7 +16,7 @@ Gibbon 3.0.0+ returns a `Gibbon::Response` instead of the response body directly
|
|
|
16
16
|
|
|
17
17
|
## Requirements
|
|
18
18
|
|
|
19
|
-
A MailChimp account and API key. You can see your API keys [here](
|
|
19
|
+
A MailChimp account and API key. You can see your API keys [here](https://admin.mailchimp.com/account/api).
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
@@ -35,9 +35,9 @@ gibbon.timeout = 30
|
|
|
35
35
|
gibbon.open_timeout = 30
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
You can read about `timeout` and `open_timeout` in the [Net::HTTP](https://ruby-
|
|
38
|
+
You can read about `timeout` and `open_timeout` in the [Net::HTTP](https://docs.ruby-lang.org/en/master/Net/HTTP.html) doc.
|
|
39
39
|
|
|
40
|
-
Now you can make requests using the resources defined in [MailChimp's docs](
|
|
40
|
+
Now you can make requests using the resources defined in [MailChimp's docs](https://mailchimp.com/developer/marketing/api/). Resource IDs
|
|
41
41
|
are specified inline and a `CRUD` (`create`, `retrieve` (or `get`), `update`, `upsert`, or `delete`) verb initiates the request. `upsert` lets you update a record, if it exists, or insert it otherwise where supported by MailChimp's API.
|
|
42
42
|
|
|
43
43
|
***Note*** `upsert` requires Gibbon version 2.1.0 or newer!
|
|
@@ -84,7 +84,7 @@ Pass `symbolize_keys: true` to use symbols (instead of strings) as hash keys in
|
|
|
84
84
|
gibbon = Gibbon::Request.new(api_key: "your_api_key", symbolize_keys: true)
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
MailChimp's [resource documentation](
|
|
87
|
+
MailChimp's [resource documentation](https://mailchimp.com/developer/marketing/api/) is a list of available resources.
|
|
88
88
|
|
|
89
89
|
## Debug Logging
|
|
90
90
|
|
|
@@ -241,7 +241,7 @@ gibbon.batches(batch_id).retrieve
|
|
|
241
241
|
```
|
|
242
242
|
|
|
243
243
|
***Note*** This response truncated for brevity. Reference the MailChimp
|
|
244
|
-
[API documentation for Batch Operations](
|
|
244
|
+
[API documentation for Batch Operations](https://mailchimp.com/developer/marketing/api/batches/) for more details.
|
|
245
245
|
|
|
246
246
|
### Fields
|
|
247
247
|
|
|
@@ -363,7 +363,7 @@ The response body (i.e. `response.body`) looks someting like this (unrelated thi
|
|
|
363
363
|
{"id"=>"...", "email_address"=>"...", ..., "interests"=>{"3def637141"=>true, "f7cc4ee841"=>false, "fcdc951b9f"=>false, "3daf3cf27d"=>true, "293a3703ed"=>false, "72370e0d1f"=>false, "d434d21a1c"=>false, "bdb1ff199f"=>false, "a54e78f203"=>false, "c4527fd018"=>false} ...}
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
-
The API returns a map of interest ID to boolean value. Now we to get interest details so we know what these interest IDs map to. Looking at [this doc page](
|
|
366
|
+
The API returns a map of interest ID to boolean value. Now we to get interest details so we know what these interest IDs map to. Looking at [this doc page](https://mailchimp.com/developer/marketing/api/interests/), we need to do this:
|
|
367
367
|
|
|
368
368
|
```ruby
|
|
369
369
|
gibbon.lists(list_id).interest_categories.retrieve
|
|
@@ -400,7 +400,7 @@ end
|
|
|
400
400
|
|
|
401
401
|
### Other
|
|
402
402
|
|
|
403
|
-
Overriding Gibbon's API endpoint (i.e. if using an access token from OAuth and have the `api_endpoint` from the [metadata](
|
|
403
|
+
Overriding Gibbon's API endpoint (i.e. if using an access token from OAuth and have the `api_endpoint` from the [metadata](https://mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/)):
|
|
404
404
|
|
|
405
405
|
```ruby
|
|
406
406
|
Gibbon::Request.api_endpoint = "https://us1.api.mailchimp.com"
|
data/gibbon.gemspec
CHANGED
|
@@ -7,23 +7,22 @@ Gem::Specification.new do |s|
|
|
|
7
7
|
s.version = Gibbon::VERSION
|
|
8
8
|
s.authors = ["Amro Mousa"]
|
|
9
9
|
s.email = ["amromousa@gmail.com"]
|
|
10
|
-
s.homepage = "
|
|
10
|
+
s.homepage = "https://github.com/amro/gibbon"
|
|
11
11
|
|
|
12
12
|
s.summary = %q{A wrapper for MailChimp API 3.0}
|
|
13
13
|
s.description = %q{A wrapper for MailChimp API 3.0}
|
|
14
14
|
s.license = "MIT"
|
|
15
15
|
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
|
17
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
18
|
s.require_paths = ["lib"]
|
|
20
|
-
s.required_ruby_version = '>=
|
|
19
|
+
s.required_ruby_version = '>= 3.1.0'
|
|
21
20
|
|
|
22
21
|
s.add_dependency('faraday', '>= 1.0')
|
|
23
22
|
s.add_dependency('multi_json', '>= 1.11.0')
|
|
24
23
|
|
|
25
24
|
s.add_development_dependency 'rake'
|
|
26
|
-
s.add_development_dependency "rspec", "3.
|
|
25
|
+
s.add_development_dependency "rspec", "~> 3.13"
|
|
27
26
|
s.add_development_dependency 'webmock', '~> 3.8'
|
|
28
27
|
|
|
29
28
|
end
|
data/lib/gibbon/api_request.rb
CHANGED
|
@@ -106,6 +106,10 @@ module Gibbon
|
|
|
106
106
|
# Helpers
|
|
107
107
|
|
|
108
108
|
def handle_error(error)
|
|
109
|
+
# Errors we raised ourselves (e.g. unparseable response bodies) already
|
|
110
|
+
# carry their details; re-wrapping them here would strip those attributes
|
|
111
|
+
raise error if error.is_a?(MailChimpError)
|
|
112
|
+
|
|
109
113
|
error_params = {}
|
|
110
114
|
|
|
111
115
|
begin
|
|
@@ -146,7 +150,7 @@ module Gibbon
|
|
|
146
150
|
end
|
|
147
151
|
|
|
148
152
|
def rest_client
|
|
149
|
-
client = Faraday.new(self.api_url, proxy: self.proxy, ssl: {
|
|
153
|
+
client = Faraday.new(self.api_url, proxy: self.proxy, ssl: { min_version: :TLS1_2 }) do |faraday|
|
|
150
154
|
faraday.response :raise_error
|
|
151
155
|
faraday.adapter adapter
|
|
152
156
|
if @request_builder.debug
|
data/lib/gibbon/version.rb
CHANGED
|
@@ -66,4 +66,133 @@ describe Gibbon::APIRequest do
|
|
|
66
66
|
|
|
67
67
|
include_examples 'client error handling'
|
|
68
68
|
end
|
|
69
|
+
|
|
70
|
+
context 'Faraday::ServerError' do
|
|
71
|
+
let(:error_class) { Faraday::ServerError }
|
|
72
|
+
|
|
73
|
+
include_examples 'client error handling'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "error responses over HTTP" do
|
|
77
|
+
it "raises a MailChimpError with details parsed from a 4xx JSON response" do
|
|
78
|
+
error_body = '{"title": "Invalid Resource", "detail": "The resource submitted could not be validated.", "status": 422}'
|
|
79
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
80
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
81
|
+
.to_return(status: 422, body: error_body, headers: { 'Content-Type' => 'application/json' })
|
|
82
|
+
|
|
83
|
+
begin
|
|
84
|
+
@gibbon.lists.retrieve
|
|
85
|
+
fail "expected a Gibbon::MailChimpError"
|
|
86
|
+
rescue Gibbon::MailChimpError => e
|
|
87
|
+
expect(e.status_code).to eq 422
|
|
88
|
+
expect(e.title).to eq "Invalid Resource"
|
|
89
|
+
expect(e.detail).to eq "The resource submitted could not be validated."
|
|
90
|
+
expect(e.raw_body).to eq error_body
|
|
91
|
+
expect(e.body).to eq MultiJson.load(error_body)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "raises a MailChimpError on a 5xx response" do
|
|
96
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
97
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
98
|
+
.to_return(status: 503, body: '{"title": "Service Unavailable"}')
|
|
99
|
+
|
|
100
|
+
begin
|
|
101
|
+
@gibbon.lists.retrieve
|
|
102
|
+
fail "expected a Gibbon::MailChimpError"
|
|
103
|
+
rescue Gibbon::MailChimpError => e
|
|
104
|
+
expect(e.status_code).to eq 503
|
|
105
|
+
expect(e.title).to eq "Service Unavailable"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "response parsing" do
|
|
111
|
+
it "returns a Gibbon::Response with the parsed body and headers" do
|
|
112
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
113
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
114
|
+
.to_return(status: 200, body: '{"lists": [{"id": "abc123"}]}', headers: { 'Content-Type' => 'application/json' })
|
|
115
|
+
|
|
116
|
+
response = @gibbon.lists.retrieve
|
|
117
|
+
expect(response).to be_a Gibbon::Response
|
|
118
|
+
expect(response.body).to eq({ "lists" => [{ "id" => "abc123" }] })
|
|
119
|
+
expect(response.headers["content-type"]).to eq "application/json"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "symbolizes response keys when symbolize_keys is true" do
|
|
123
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
124
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
125
|
+
.to_return(status: 200, body: '{"lists": [{"id": "abc123"}]}')
|
|
126
|
+
|
|
127
|
+
response = Gibbon::Request.new(api_key: api_key, symbolize_keys: true).lists.retrieve
|
|
128
|
+
expect(response.body).to eq({ lists: [{ id: "abc123" }] })
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "returns nil for an empty response body" do
|
|
132
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
133
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
134
|
+
.to_return(status: 200, body: "")
|
|
135
|
+
|
|
136
|
+
expect(@gibbon.lists.retrieve).to be_nil
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "raises a MailChimpError with details intact for an unparseable success response" do
|
|
140
|
+
stub_request(:get, "#{@api_root}/lists")
|
|
141
|
+
.with(basic_auth: @basic_auth_credentials)
|
|
142
|
+
.to_return(status: 200, body: "not json")
|
|
143
|
+
|
|
144
|
+
begin
|
|
145
|
+
@gibbon.lists.retrieve
|
|
146
|
+
fail "expected a Gibbon::MailChimpError"
|
|
147
|
+
rescue Gibbon::MailChimpError => e
|
|
148
|
+
expect(e.title).to eq "UNPARSEABLE_RESPONSE"
|
|
149
|
+
expect(e.status_code).to eq 500
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context "configure_request" do
|
|
155
|
+
it "sets params, headers, body, and timeouts on the request" do
|
|
156
|
+
gibbon = Gibbon::Request.new(api_key: api_key, timeout: 45, open_timeout: 15)
|
|
157
|
+
api_request = Gibbon::APIRequest.new(builder: gibbon.lists)
|
|
158
|
+
request = Struct.new(:params, :headers, :body, :options).new({}, {}, nil, Faraday::RequestOptions.new)
|
|
159
|
+
|
|
160
|
+
api_request.send(:configure_request, request: request, params: { "count" => "10" }, headers: { "X-Custom" => "value" }, body: '{"a":1}')
|
|
161
|
+
|
|
162
|
+
expect(request.params).to eq({ "count" => "10" })
|
|
163
|
+
expect(request.headers).to eq({ "Content-Type" => "application/json", "X-Custom" => "value" })
|
|
164
|
+
expect(request.body).to eq '{"a":1}'
|
|
165
|
+
expect(request.options.timeout).to eq 45
|
|
166
|
+
expect(request.options.open_timeout).to eq 15
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
context "rest_client configuration" do
|
|
171
|
+
it "includes the logger middleware when debug is enabled" do
|
|
172
|
+
gibbon = Gibbon::Request.new(api_key: api_key, debug: true)
|
|
173
|
+
client = Gibbon::APIRequest.new(builder: gibbon.lists).send(:rest_client)
|
|
174
|
+
expect(client.builder.handlers).to include(Faraday::Response::Logger)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "omits the logger middleware by default" do
|
|
178
|
+
client = Gibbon::APIRequest.new(builder: @gibbon.lists).send(:rest_client)
|
|
179
|
+
expect(client.builder.handlers).not_to include(Faraday::Response::Logger)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "configures the proxy" do
|
|
183
|
+
gibbon = Gibbon::Request.new(api_key: api_key, proxy: "http://proxy.example.com:8080")
|
|
184
|
+
client = Gibbon::APIRequest.new(builder: gibbon.lists).send(:rest_client)
|
|
185
|
+
expect(client.proxy.host).to eq "proxy.example.com"
|
|
186
|
+
expect(client.proxy.port).to eq 8080
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
context "rest_client ssl configuration" do
|
|
191
|
+
it "requires TLS 1.2 as a minimum without capping the TLS version" do
|
|
192
|
+
api_request = Gibbon::APIRequest.new(builder: @gibbon.lists)
|
|
193
|
+
client = api_request.send(:rest_client)
|
|
194
|
+
expect(client.ssl.min_version).to eq :TLS1_2
|
|
195
|
+
expect(client.ssl.max_version).to be_nil
|
|
196
|
+
end
|
|
197
|
+
end
|
|
69
198
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Gibbon::Helpers do
|
|
4
|
+
let(:helper) { Class.new { include Gibbon::Helpers }.new }
|
|
5
|
+
|
|
6
|
+
describe "#get_data_center_from_api_key" do
|
|
7
|
+
it "returns an empty string for a nil api key" do
|
|
8
|
+
expect(helper.get_data_center_from_api_key(nil)).to eq("")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "returns an empty string for an api key without a data center" do
|
|
12
|
+
expect(helper.get_data_center_from_api_key("1234")).to eq("")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "returns the data center with a trailing dot" do
|
|
16
|
+
expect(helper.get_data_center_from_api_key("1234-us1")).to eq("us1.")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "uses the last segment of a key containing multiple hyphens" do
|
|
20
|
+
expect(helper.get_data_center_from_api_key("12-34-us10")).to eq("us10.")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "strips non-alphanumeric characters to prevent domain injection" do
|
|
24
|
+
expect(helper.get_data_center_from_api_key("1234-attacker.net/path?")).to eq("attackernetpath.")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -46,4 +46,22 @@ describe Gibbon::MailChimpError do
|
|
|
46
46
|
it 'sets the status_code attribute' do
|
|
47
47
|
expect(@gibbon.status_code).to eq(params[:status_code])
|
|
48
48
|
end
|
|
49
|
+
|
|
50
|
+
context "without params" do
|
|
51
|
+
before do
|
|
52
|
+
@gibbon = Gibbon::MailChimpError.new(message)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "leaves the attributes nil" do
|
|
56
|
+
expect(@gibbon.title).to be_nil
|
|
57
|
+
expect(@gibbon.detail).to be_nil
|
|
58
|
+
expect(@gibbon.body).to be_nil
|
|
59
|
+
expect(@gibbon.raw_body).to be_nil
|
|
60
|
+
expect(@gibbon.status_code).to be_nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "still includes the attributes in the message" do
|
|
64
|
+
expect(@gibbon.message).to eq "Foo @title=nil, @detail=nil, @body=nil, @raw_body=nil, @status_code=nil"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
49
67
|
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'webmock/rspec'
|
|
3
|
+
|
|
4
|
+
describe Gibbon::Request do
|
|
5
|
+
let(:api_key) { "1234-us1" }
|
|
6
|
+
let(:api_root) { "https://us1.api.mailchimp.com/3.0" }
|
|
7
|
+
let(:basic_auth_credentials) { ['apikey', api_key] }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
@gibbon = Gibbon::Request.new(api_key: api_key)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "path building" do
|
|
14
|
+
it "builds a path from chained calls" do
|
|
15
|
+
@gibbon.lists("list123").members
|
|
16
|
+
expect(@gibbon.path).to eq("lists/list123/members")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "replaces underscores with hyphens" do
|
|
20
|
+
@gibbon.lists("list123").interest_categories
|
|
21
|
+
expect(@gibbon.path).to eq("lists/list123/interest-categories")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "downcases path parts" do
|
|
25
|
+
@gibbon.LISTS
|
|
26
|
+
expect(@gibbon.path).to eq("lists")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "responds to any method" do
|
|
30
|
+
expect(@gibbon.respond_to?(:anything_at_all)).to be true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "appends 'send' to the path when called without arguments" do
|
|
34
|
+
@gibbon.campaigns("abc").actions.send
|
|
35
|
+
expect(@gibbon.path).to eq("campaigns/abc/actions/send")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "dispatches send with arguments as a regular method call" do
|
|
39
|
+
expect(@gibbon.send(:api_key)).to eq(api_key)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "resets the path after a request" do
|
|
43
|
+
stub_request(:get, "#{api_root}/lists").with(basic_auth: basic_auth_credentials).to_return(status: 200)
|
|
44
|
+
@gibbon.lists.retrieve
|
|
45
|
+
expect(@gibbon.path).to eq("")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "resets the path when a request raises" do
|
|
49
|
+
stub_request(:get, "#{api_root}/lists").with(basic_auth: basic_auth_credentials).to_return(status: 500, body: "{}")
|
|
50
|
+
expect { @gibbon.lists.retrieve }.to raise_error(Gibbon::MailChimpError)
|
|
51
|
+
expect(@gibbon.path).to eq("")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "HTTP verb mapping" do
|
|
56
|
+
let(:body) { { name: "Foo" } }
|
|
57
|
+
|
|
58
|
+
it "maps create to POST" do
|
|
59
|
+
stub = stub_request(:post, "#{api_root}/lists")
|
|
60
|
+
.with(body: MultiJson.dump(body), basic_auth: basic_auth_credentials, headers: { 'Content-Type' => 'application/json' })
|
|
61
|
+
.to_return(status: 200)
|
|
62
|
+
@gibbon.lists.create(body: body)
|
|
63
|
+
expect(stub).to have_been_requested
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "maps update to PATCH" do
|
|
67
|
+
stub = stub_request(:patch, "#{api_root}/lists/list123")
|
|
68
|
+
.with(body: MultiJson.dump(body), basic_auth: basic_auth_credentials, headers: { 'Content-Type' => 'application/json' })
|
|
69
|
+
.to_return(status: 200)
|
|
70
|
+
@gibbon.lists("list123").update(body: body)
|
|
71
|
+
expect(stub).to have_been_requested
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "maps upsert to PUT" do
|
|
75
|
+
stub = stub_request(:put, "#{api_root}/lists/list123")
|
|
76
|
+
.with(body: MultiJson.dump(body), basic_auth: basic_auth_credentials, headers: { 'Content-Type' => 'application/json' })
|
|
77
|
+
.to_return(status: 200)
|
|
78
|
+
@gibbon.lists("list123").upsert(body: body)
|
|
79
|
+
expect(stub).to have_been_requested
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "maps retrieve to GET" do
|
|
83
|
+
stub = stub_request(:get, "#{api_root}/lists").with(basic_auth: basic_auth_credentials).to_return(status: 200)
|
|
84
|
+
@gibbon.lists.retrieve
|
|
85
|
+
expect(stub).to have_been_requested
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "maps get to GET" do
|
|
89
|
+
stub = stub_request(:get, "#{api_root}/lists").with(basic_auth: basic_auth_credentials).to_return(status: 200)
|
|
90
|
+
@gibbon.lists.get
|
|
91
|
+
expect(stub).to have_been_requested
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "maps delete to DELETE" do
|
|
95
|
+
stub = stub_request(:delete, "#{api_root}/lists/list123").with(basic_auth: basic_auth_credentials).to_return(status: 204)
|
|
96
|
+
@gibbon.lists("list123").delete
|
|
97
|
+
expect(stub).to have_been_requested
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "request options" do
|
|
102
|
+
it "passes query params" do
|
|
103
|
+
stub = stub_request(:get, "#{api_root}/lists")
|
|
104
|
+
.with(query: { "count" => "10", "offset" => "20" }, basic_auth: basic_auth_credentials)
|
|
105
|
+
.to_return(status: 200)
|
|
106
|
+
@gibbon.lists.retrieve(params: { "count" => "10", "offset" => "20" })
|
|
107
|
+
expect(stub).to have_been_requested
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "passes custom headers" do
|
|
111
|
+
stub = stub_request(:get, "#{api_root}/lists")
|
|
112
|
+
.with(headers: { 'X-Custom' => 'custom-value' }, basic_auth: basic_auth_credentials)
|
|
113
|
+
.to_return(status: 200)
|
|
114
|
+
@gibbon.lists.retrieve(headers: { 'X-Custom' => 'custom-value' })
|
|
115
|
+
expect(stub).to have_been_requested
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "api key handling" do
|
|
120
|
+
it "strips whitespace from the api key" do
|
|
121
|
+
gibbon = Gibbon::Request.new(api_key: " #{api_key} ")
|
|
122
|
+
expect(gibbon.api_key).to eq(api_key)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "class-level requests" do
|
|
127
|
+
before do
|
|
128
|
+
Gibbon::Request.api_key = api_key
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
after do
|
|
132
|
+
Gibbon::Request.api_key = nil
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "makes requests directly on the class" do
|
|
136
|
+
stub = stub_request(:get, "#{api_root}/lists").with(basic_auth: basic_auth_credentials).to_return(status: 200)
|
|
137
|
+
Gibbon::Request.lists.retrieve
|
|
138
|
+
expect(stub).to have_been_requested
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Gibbon::Response do
|
|
4
|
+
it "defaults body and headers to empty hashes" do
|
|
5
|
+
response = Gibbon::Response.new
|
|
6
|
+
expect(response.body).to eq({})
|
|
7
|
+
expect(response.headers).to eq({})
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "exposes the body and headers it is given" do
|
|
11
|
+
body = { "id" => "abc" }
|
|
12
|
+
headers = { "content-type" => "application/json" }
|
|
13
|
+
response = Gibbon::Response.new(body: body, headers: headers)
|
|
14
|
+
expect(response.body).to eq(body)
|
|
15
|
+
expect(response.headers).to eq(headers)
|
|
16
|
+
end
|
|
17
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gibbon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Amro Mousa
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: faraday
|
|
@@ -56,16 +55,16 @@ dependencies:
|
|
|
56
55
|
name: rspec
|
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
|
58
57
|
requirements:
|
|
59
|
-
- -
|
|
58
|
+
- - "~>"
|
|
60
59
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 3.
|
|
60
|
+
version: '3.13'
|
|
62
61
|
type: :development
|
|
63
62
|
prerelease: false
|
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
64
|
requirements:
|
|
66
|
-
- -
|
|
65
|
+
- - "~>"
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 3.
|
|
67
|
+
version: '3.13'
|
|
69
68
|
- !ruby/object:Gem::Dependency
|
|
70
69
|
name: webmock
|
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,15 +106,17 @@ files:
|
|
|
107
106
|
- lib/gibbon/response.rb
|
|
108
107
|
- lib/gibbon/version.rb
|
|
109
108
|
- spec/gibbon/api_request_spec.rb
|
|
109
|
+
- spec/gibbon/gibbon_helpers_spec.rb
|
|
110
110
|
- spec/gibbon/gibbon_spec.rb
|
|
111
111
|
- spec/gibbon/mailchimp_error_spec.rb
|
|
112
|
+
- spec/gibbon/request_spec.rb
|
|
113
|
+
- spec/gibbon/response_spec.rb
|
|
112
114
|
- spec/gibbon/upsert_spec.rb
|
|
113
115
|
- spec/spec_helper.rb
|
|
114
|
-
homepage:
|
|
116
|
+
homepage: https://github.com/amro/gibbon
|
|
115
117
|
licenses:
|
|
116
118
|
- MIT
|
|
117
119
|
metadata: {}
|
|
118
|
-
post_install_message:
|
|
119
120
|
rdoc_options: []
|
|
120
121
|
require_paths:
|
|
121
122
|
- lib
|
|
@@ -123,20 +124,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
123
124
|
requirements:
|
|
124
125
|
- - ">="
|
|
125
126
|
- !ruby/object:Gem::Version
|
|
126
|
-
version:
|
|
127
|
+
version: 3.1.0
|
|
127
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
129
|
requirements:
|
|
129
130
|
- - ">="
|
|
130
131
|
- !ruby/object:Gem::Version
|
|
131
132
|
version: '0'
|
|
132
133
|
requirements: []
|
|
133
|
-
rubygems_version:
|
|
134
|
-
signing_key:
|
|
134
|
+
rubygems_version: 4.0.16
|
|
135
135
|
specification_version: 4
|
|
136
136
|
summary: A wrapper for MailChimp API 3.0
|
|
137
|
-
test_files:
|
|
138
|
-
- spec/gibbon/api_request_spec.rb
|
|
139
|
-
- spec/gibbon/gibbon_spec.rb
|
|
140
|
-
- spec/gibbon/mailchimp_error_spec.rb
|
|
141
|
-
- spec/gibbon/upsert_spec.rb
|
|
142
|
-
- spec/spec_helper.rb
|
|
137
|
+
test_files: []
|