blanket_wrapper 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.