blanket_wrapper 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80891d01cd391a6ca57b8cd1d2d266a479529a25
4
- data.tar.gz: 8276eaabece824b10f87d5c05bfa043218ca4538
3
+ metadata.gz: d4919971f12da2062b5d5cd9b0152d820acce367
4
+ data.tar.gz: d5ffa6e823b1a2a00647d13b23a85c78a71b52ae
5
5
  SHA512:
6
- metadata.gz: 1206873393b17fc7f110f04d019cc083f0a7b6bd6ef6c2fa2a8ac2741f093b3458d61e5267b5236cefd12f423f7ba2a8b4191ddd0756fc5751f1b5b220652b01
7
- data.tar.gz: c6591d74a75cc068784d9fa9e9327f8d6ebcea80265bb8c6ebf30f6e69268dd093dbfcb8d92172b015010bee2a2ed81a182f11b592bcda40292ce84300834b2b
6
+ metadata.gz: 1e489971f0588e4d32bc874e22fbe088f13d34cddacd67966e4fb71deb60d234285d8b48c8200114dcb28bdf36cb93654b54bfbf4dc4e0ee8690bd8f5563586d
7
+ data.tar.gz: 23a7795896868c49f0df75162fc0093f34e9ab63f2f83eb8a09624df8da7c30326cd722fd699922c07db432922ca586da8d79f5e625390b9400c11cb7fd359fc
data/README.md CHANGED
@@ -7,6 +7,19 @@
7
7
 
8
8
  A dead simple API wrapper.
9
9
 
10
+ **Table of Contents**
11
+
12
+ - [Installation](#installation)
13
+ - [Usage](#usage)
14
+ - [Quick demo](#quick-demo)
15
+ - [How it works](#how-it-works)
16
+ - [Responses](#responses)
17
+ - [Request Parameters](#request-parameters)
18
+ - [Headers](#headers)
19
+ - [Extensions](#extensions)
20
+ - [Handling Exceptions](#handling-exceptions)
21
+ - [Contributing](#contributing)
22
+
10
23
  ## Installation
11
24
 
12
25
  Add this line to your application's Gemfile:
@@ -28,6 +41,8 @@ Or install it yourself as:
28
41
  ### Quick demo
29
42
 
30
43
  ```ruby
44
+ require 'blanket'
45
+
31
46
  github = Blanket.wrap("https://api.github.com")
32
47
 
33
48
  # Get some user's info
@@ -104,6 +119,14 @@ repos.map(&:name)
104
119
  # => ["analytics-ios", "aztec", "fusebox", ...]
105
120
  ```
106
121
 
122
+ ### Request Body
123
+ You can make requests with body using the `body` option:
124
+
125
+ ```ruby
126
+ api = Blanket::wrap("http://api.example.org")
127
+ api.messages.post(body: 'Hello')
128
+ ```
129
+
107
130
  ### Request Parameters
108
131
  Blanket supports appending parameters to your requests:
109
132
 
@@ -112,6 +135,12 @@ api.users(55).get(params: {foo: 'bar'})
112
135
  # => "http://api.example.org/users/55?foo=bar"
113
136
  ```
114
137
 
138
+ You can also set default params for all your requests on initialization:
139
+
140
+ ```ruby
141
+ api = Blanket::wrap("http://api.example.org", params: {access_token: 'my secret token'})
142
+ ```
143
+
115
144
  ### Headers
116
145
  HTTP Headers are always useful when accessing an API, so Blanket makes it easy for you to specify them, either globally or on a per-request basis:
117
146
 
@@ -157,7 +186,7 @@ end
157
186
 
158
187
  ## Contributing
159
188
 
160
- 1. Fork it ( https://github.com/[my-github-username]/blanket/fork )
189
+ 1. Fork it ( https://github.com/inf0rmer/blanket/fork )
161
190
  2. Create your feature branch (`git checkout -b my-new-feature`)
162
191
  3. Commit your changes (`git commit -am 'Add some feature'`)
163
192
  4. Push to the branch (`git push origin my-new-feature`)
@@ -1,28 +1,7 @@
1
1
  module Blanket
2
2
 
3
- # A Map of HTTP status codes and their names
4
- STATUSES = {100 => 'Continue',
5
- 101 => 'Switching Protocols',
6
- 102 => 'Processing', #WebDAV
7
-
8
- 200 => 'OK',
9
- 201 => 'Created',
10
- 202 => 'Accepted',
11
- 203 => 'Non-Authoritative Information', # http/1.1
12
- 204 => 'No Content',
13
- 205 => 'Reset Content',
14
- 206 => 'Partial Content',
15
- 207 => 'Multi-Status', #WebDAV
16
-
17
- 300 => 'Multiple Choices',
18
- 301 => 'Moved Permanently',
19
- 302 => 'Found',
20
- 303 => 'See Other', # http/1.1
21
- 304 => 'Not Modified',
22
- 305 => 'Use Proxy', # http/1.1
23
- 306 => 'Switch Proxy', # no longer used
24
- 307 => 'Temporary Redirect', # http/1.1
25
-
3
+ # A Map of "error" HTTP status codes and their names
4
+ STATUSES = {
26
5
  400 => 'Bad Request',
27
6
  401 => 'Unauthorized',
28
7
  402 => 'Payment Required',
@@ -101,21 +80,24 @@ module Blanket
101
80
  "#{message}: #{body}"
102
81
  end
103
82
 
104
- # Returns a stringified error message
105
- def to_s
106
- inspect
107
- end
83
+ alias_method :to_s, :inspect
108
84
  end
109
85
 
110
86
  # We will a create an exception for each status code, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
111
87
  module Exceptions
112
88
  # Map http status codes to the corresponding exception class
113
89
  EXCEPTIONS_MAP = {}
90
+
91
+ def self.generate_from_response(response)
92
+ (EXCEPTIONS_MAP[response.code] || Exception).new(response)
93
+ end
114
94
  end
115
95
 
116
96
  STATUSES.each_pair do |code, message|
117
97
  klass = Class.new(Exception) do
118
- send(:define_method, :message) {"#{code ? "#{code} " : ''}#{message}"}
98
+ define_method :message do
99
+ "#{code} #{message}"
100
+ end
119
101
  end
120
102
 
121
103
  klass_constant = const_set message.delete(' \-\''), klass
@@ -21,22 +21,19 @@ module Blanket
21
21
  # Allows accessing the payload's JSON keys through methods.
22
22
  def method_missing(method, *args, &block)
23
23
  if payload.respond_to? method
24
- payload.send method, *args, &block
24
+ payload.public_send method, *args, &block
25
25
  else
26
26
  super
27
27
  end
28
28
  end
29
29
 
30
30
  def payload_from_json(json)
31
- if json
32
- parsed = [json].flatten.map do |item|
33
- RecursiveOpenStruct.new item, :recurse_over_arrays => true
34
- end
35
-
36
- (parsed.count == 1) ? parsed.first : parsed
37
- else
38
- nil
31
+ parsed = [json].flatten.map do |item|
32
+ RecursiveOpenStruct.new item, recurse_over_arrays: true
39
33
  end
34
+
35
+ (parsed.count == 1) ? parsed.first : parsed
40
36
  end
37
+
41
38
  end
42
39
  end
@@ -1,4 +1,4 @@
1
1
  module Blanket
2
2
  # Current gem version
3
- VERSION = "1.1.0"
3
+ VERSION = "1.2.0"
4
4
  end
@@ -1,5 +1,4 @@
1
1
  module Blanket
2
- # The Wrapper class wraps an API
3
2
  class Wrapper
4
3
  class << self
5
4
  private
@@ -7,7 +6,7 @@ module Blanket
7
6
  # @method $1()
8
7
  # Performs a $1 request on the wrapped URL
9
8
  # @param [String, Symbol, Numeric] id The resource identifier to attach to the last part of the request
10
- # @param [Hash] options An options hash with values for :headers, :extension and :params
9
+ # @param [Hash] options An options hash with values for :headers, :extension, :params and :body
11
10
  # @return [Blanket::Response, Array] A wrapped Blanket::Response or an Array
12
11
  def add_action(action)
13
12
  define_method(action) do |id=nil, options={}|
@@ -20,6 +19,10 @@ module Blanket
20
19
  # should be applied to all requests
21
20
  attr_accessor :headers
22
21
 
22
+ # Attribute accessor for params that
23
+ # should be applied to all requests
24
+ attr_accessor :params
25
+
23
26
  # Attribute accessor for file extension that
24
27
  # should be appended to all requests
25
28
  attr_accessor :extension
@@ -32,12 +35,13 @@ module Blanket
32
35
 
33
36
  # Wraps the base URL for an API
34
37
  # @param [String, Symbol] base_uri The root URL of the API you wish to wrap.
35
- # @param [Hash] options An options hash with global values for :headers and :extension
38
+ # @param [Hash] options An options hash with global values for :headers, :extension and :params
36
39
  # @return [Blanket] The Blanket object wrapping the API
37
40
  def initialize(base_uri, options={})
38
41
  @base_uri = base_uri
39
42
  @uri_parts = []
40
- @headers = (options[:headers].nil?) ? {} : options[:headers]
43
+ @headers = options[:headers] || {}
44
+ @params = options[:params] || {}
41
45
  @extension = options[:extension]
42
46
  end
43
47
 
@@ -46,7 +50,8 @@ module Blanket
46
50
  def method_missing(method, *args, &block)
47
51
  Wrapper.new uri_from_parts([method, args.first]), {
48
52
  headers: @headers,
49
- extension: @extension
53
+ extension: @extension,
54
+ params: @params
50
55
  }
51
56
  end
52
57
 
@@ -57,34 +62,37 @@ module Blanket
57
62
  end
58
63
 
59
64
  headers = merged_headers(options[:headers])
65
+ params = merged_params(options[:params])
60
66
  uri = uri_from_parts([id])
61
67
 
62
68
  if @extension
63
69
  uri = "#{uri}.#{extension}"
64
70
  end
65
71
 
66
- response = HTTParty.send(method, uri, {
67
- query: options[:params],
68
- headers: headers
69
- }.reject { |k, v| v.nil? || v.empty? })
72
+ response = HTTParty.public_send(method, uri, {
73
+ query: params,
74
+ headers: headers,
75
+ body: options[:body]
76
+ }.reject { |_, value| value.nil? || value.empty? })
70
77
 
71
78
  if response.code <= 400
72
79
  body = (response.respond_to? :body) ? response.body : nil
73
80
  (body.is_a? Array) ? body.map(Response.new) : Response.new(body)
74
81
  else
75
- raise Blanket::Exceptions::EXCEPTIONS_MAP[response.code].new(response)
82
+ raise Blanket::Exceptions.generate_from_response(response)
76
83
  end
77
84
  end
78
85
 
79
86
  def merged_headers(headers)
80
- headers = @headers.merge(headers != nil ? headers : {})
87
+ @headers.merge(headers || {})
88
+ end
89
+
90
+ def merged_params(params)
91
+ @params.merge(params || {})
81
92
  end
82
93
 
83
94
  def uri_from_parts(parts)
84
- parts
85
- .clone
86
- .compact
87
- .inject(@base_uri.clone) { |memo, part| memo << "/#{part}" }
95
+ ([@base_uri] + parts).compact.join('/')
88
96
  end
89
97
  end
90
98
  end
@@ -45,6 +45,16 @@ describe "Blanket::Wrapper" do
45
45
  expect { api.users.get }.to raise_exception(Blanket::InternalServerError)
46
46
  end
47
47
  end
48
+
49
+ describe "522, a non registered invalid status code" do
50
+ before :each do
51
+ stub_request(:get, "http://api.example.org/users").to_return(status: 522, body: "You've been met with a terrible fate, haven't you?")
52
+ end
53
+
54
+ it "raises a generic instance of Blanket::Exception" do
55
+ expect { api.users.get }.to raise_exception(Blanket::Exception)
56
+ end
57
+ end
48
58
  end
49
59
 
50
60
  describe 'Resource identification' do
@@ -104,6 +114,13 @@ describe "Blanket::Wrapper" do
104
114
 
105
115
  expect(HTTParty).to have_received(:get).with('http://api.example.org/users/55', query: {foo: 'bar'})
106
116
  end
117
+
118
+ it 'allows setting parameters globally' do
119
+ api = Blanket::wrap("http://api.example.org", params: {token: 'my secret token'})
120
+ api.users(55).get(params: {foo: 'bar'})
121
+
122
+ expect(HTTParty).to have_received(:get).with('http://api.example.org/users/55', query: {token: 'my secret token', foo: 'bar'})
123
+ end
107
124
  end
108
125
 
109
126
  describe 'URL Extension' do
@@ -126,6 +143,19 @@ describe "Blanket::Wrapper" do
126
143
  expect(HTTParty).to have_received(:get).with('http://api.example.org/users/55.xml', anything())
127
144
  end
128
145
  end
146
+
147
+ describe 'Body' do
148
+ before :each do
149
+ allow(HTTParty).to receive(:post) { StubbedResponse.new }
150
+ end
151
+
152
+ it 'allows setting the body for a request' do
153
+ api = Blanket::wrap("http://api.example.org")
154
+ api.users(55).post(body: { this_key: :this_value }.to_json)
155
+
156
+ expect(HTTParty).to have_received(:post).with('http://api.example.org/users/55', body: { this_key: :this_value }.to_json)
157
+ end
158
+ end
129
159
  end
130
160
 
131
161
  describe '#get' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blanket_wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Abrantes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-29 00:00:00.000000000 Z
11
+ date: 2015-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -220,7 +220,6 @@ files:
220
220
  - Gemfile
221
221
  - Guardfile
222
222
  - LICENSE
223
- - LICENSE.txt
224
223
  - README.md
225
224
  - Rakefile
226
225
  - blanket.gemspec
data/LICENSE.txt DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2014 Bruno Abrantes
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.