rapidash 0.2.2 → 0.3.0.beta

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: fc2547c5c59b614c4e483ade6e06387a5daa74fe
4
- data.tar.gz: be96076c18545377419376da043dfb689f319c3f
3
+ metadata.gz: 9c189f614b87a9f1d01e06b573191ab55cfc5304
4
+ data.tar.gz: 4e105da2de17bca6c15e66055e9cae54f9f2e502
5
5
  SHA512:
6
- metadata.gz: a440f140a6e093e5cdd6722251248609ac54400936d692ad9f152b83502413821ce534fb3ccbcc36d4d25138b90a35391060472cdf664ce3aab6df43b89ae299
7
- data.tar.gz: 851d7dbbc4f05207fa45c0f64c4db4b44a16f6aa0503bfbb410e2383caffc84ad7dc75639c24e93bfd8f6be5b19a5c230a5eb06622d92234515c0b81569bd31e
6
+ metadata.gz: cf3736b55a2373d1f29addff7e56904f3a7eed7c457797f984de95f7447a451e1f8d6f097e7e17125da7c0ac3dd9a65cab232090e24ac55c7b02f6290936fbb1
7
+ data.tar.gz: 2917f78dda7987f293c15d95cc760d901f597aec9d8a300552257f68720cf466d304a239b2dfadbbef07ebed9741c375985c273e5ba271ba8032c891c1d61ebe
data/.travis.yml CHANGED
@@ -4,3 +4,7 @@ rvm:
4
4
  - 1.9.2
5
5
  - 1.9.3
6
6
  - 2.0.0
7
+ - jruby-18mode
8
+ - jruby-19mode
9
+ - rbx-18mode
10
+ - rbx-19mode
@@ -0,0 +1,13 @@
1
+ require 'faraday'
2
+
3
+ module Faraday
4
+ class Response::RaiseRapidashError < Response::Middleware
5
+
6
+ def on_complete(env)
7
+ status = env[:status].to_i
8
+ klass = Rapidash.response_exception_class || Rapidash::ResponseError
9
+ raise klass.new(env) if (400..599).include?(status)
10
+ end
11
+
12
+ end
13
+ end
@@ -9,7 +9,7 @@ module Rapidash
9
9
  end
10
10
 
11
11
  class << self
12
- attr_accessor :patch, :raise_error
12
+ attr_accessor :patch, :raise_error, :extension, :encoder
13
13
 
14
14
  def method(method)
15
15
  case method
@@ -36,6 +36,32 @@ module Rapidash
36
36
  def raise_errors
37
37
  @raise_error = true
38
38
  end
39
+
40
+ # How should the request body for POST and PUT requests
41
+ # be formatted.
42
+ #
43
+ # Examples:
44
+ # class Client < Rapidash::Client
45
+ # encode_request_with :json
46
+ # end
47
+ #
48
+ # Arguments:
49
+ #
50
+ # format - Symbol. One of :url_encoded, :multipart, :json
51
+ #
52
+ # Returns String of set format
53
+ def encode_request_with(format)
54
+ format = format.to_s.to_sym
55
+
56
+ unless [:url_encoded, :multipart, :json].include?(format)
57
+ raise ArgumentError, 'you must pass one of :url_encoded, :multipart or :json to encode_request_with'
58
+ end
59
+
60
+ # Map json to multi_json to make it consistent with MutiJson parsing of responses
61
+ format = :multi_json if format == :json
62
+
63
+ @encoder ||= format
64
+ end
39
65
  end
40
66
 
41
67
  # Instance methods
@@ -79,5 +105,25 @@ module Rapidash
79
105
  def delete(url, options = {})
80
106
  request(:delete, url, options)
81
107
  end
108
+
109
+ private
110
+
111
+ def connection_builder
112
+ lambda do |builder|
113
+ builder.request self.class.encoder || :url_encoded
114
+
115
+ if self.class.respond_to?(:raise_error) && self.class.raise_error
116
+ builder.use Faraday::Response::RaiseRapidashError
117
+ end
118
+
119
+ builder.use FaradayMiddleware::FollowRedirects
120
+ builder.use FaradayMiddleware::Mashify
121
+
122
+ builder.use FaradayMiddleware::MultiJson::ParseJson, :content_type => /\bjson$/
123
+ builder.use FaradayMiddleware::ParseXml, :content_type => /\bxml$/
124
+
125
+ builder.adapter :net_http
126
+ end
127
+ end
82
128
  end
83
129
  end
@@ -1,4 +1,6 @@
1
1
  require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'faraday_middleware/multi_json'
2
4
 
3
5
  module Rapidash
4
6
  module HTTPClient
@@ -13,31 +15,21 @@ module Rapidash
13
15
 
14
16
  def connection
15
17
  raise ConfigurationError.new "Site is required" unless site
16
- @connection ||= Faraday.new(site)
18
+
19
+ @connection ||= Faraday.new(site) do |builder|
20
+ if login || password
21
+ builder.use Faraday::Request::BasicAuthentication, login, password
22
+ end
23
+
24
+ connection_builder.call(builder)
25
+ end
17
26
  end
18
27
 
19
28
  def request(verb, url, options = {})
20
29
  url = connection.build_url(normalize_url(url), options[:params]).to_s
21
- response = connection.run_request verb, url, options[:body], options[:header] do |request|
22
- request.headers.update(:Authorization => connection.basic_auth(login, password)) if login && password
23
- end
30
+ response = connection.run_request(verb, url, options[:body], options[:header])
24
31
 
25
- process_response(response, verb, options)
26
- end
27
-
28
- def process_response(response, verb, options)
29
- # "foo"[0] does not work in 1.8.7, "foo"[0,1] is required
30
- case response.status.to_s[0, 1]
31
- when "5", "4"
32
- error = ResponseError.new(response)
33
- raise error if self.class.respond_to?(:raise_error) && self.class.raise_error
34
- return nil
35
- #Handle redirects
36
- when "3"
37
- request(verb, response.headers["location"], options)
38
- when "2"
39
- return Response.new(response)
40
- end
32
+ response.body
41
33
  end
42
34
  end
43
35
  end
@@ -25,7 +25,7 @@ module Rapidash
25
25
  options[:raise_errors] = self.class.respond_to?(:raise_error) && self.class.raise_error
26
26
  response = oauth_access_token.send(verb.to_sym, "#{site}/#{url}", options)
27
27
 
28
- Response.new(response)
28
+ response.body
29
29
  end
30
30
 
31
31
  def access_token_from_code(code, url)
@@ -36,7 +36,7 @@ module Rapidash
36
36
  private
37
37
 
38
38
  def client
39
- @oauth_client ||= ::OAuth2::Client.new(uid, secret, :site => site)
39
+ @oauth_client ||= ::OAuth2::Client.new(uid, secret, :site => site, :connection_build => connection_builder)
40
40
  end
41
41
 
42
42
  def oauth_access_token
@@ -0,0 +1,74 @@
1
+ module Rapidash
2
+
3
+ # Rapidash::ResponseError
4
+ # Exception that gets raised if the response is an error (4xx or 5xx)
5
+ # Raised by Faraday::Response::RaiseRapidashError
6
+ # see lib/faraday/response/raise_rapidash_error.rb
7
+ #
8
+ # Formats a readable error message including HTTP status, method and requested URL
9
+ #
10
+ # Examples:
11
+ #
12
+ # client.posts.create!(title: '')
13
+ # Rapidash::ResponseError: 422 POST http://acme.com/api/v1/posts.json
14
+ #
15
+ # begin
16
+ # client.posts.create!(title: '')
17
+ # rescue Rapidash::ResponseError => response
18
+ # response.status # => 422
19
+ # response.method # => "POST"
20
+ # response.url # => "http://acme.com/api/v1/posts.json"
21
+ # response.body # => "{"errors":["title can't be blank", "body can't be blank"]}"
22
+ # end
23
+ #
24
+ # Hint: Can be easily sub-classed to provide a custom exception handler class
25
+ # with specific error formatting. Defining an `errors` method that returns a String or Array
26
+ # will include the errors in the exception message:
27
+ #
28
+ # class MyCustomResponseError < Rapidash::ResponseError
29
+ # def errors
30
+ # data = JSON.parse(body)
31
+ # data['errors']
32
+ # end
33
+ # end
34
+ #
35
+ # Rapidash.response_exception_class = MyCustomResponseError
36
+ #
37
+ # client.posts.create!(title: '')
38
+ # MyCustomResponseError: 422 POST http://acme.com/api/v1/posts.json | Errors: title can't be blank, body can't be blank
39
+ #
40
+ # begin
41
+ # client.posts.create!(title: '')
42
+ # rescue Rapidash::ResponseError => response
43
+ # response.status # => 422
44
+ # response.errors # => ["title can't be blank", "body can't be blank"]
45
+ # end
46
+ #
47
+ class ResponseError < StandardError
48
+ attr_reader :response, :body, :status, :method, :url
49
+
50
+ def initialize(response = nil)
51
+ @response = response
52
+
53
+ @body = response[:body]
54
+ @status = response[:status].to_i
55
+ @method = response[:method].to_s.upcase
56
+ @url = response[:url]
57
+
58
+ super(message)
59
+ end
60
+
61
+ private
62
+
63
+ def message
64
+ msg = "#{status} #{method} #{url}"
65
+
66
+ if respond_to?(:errors) && !(errors.blank?)
67
+ errors.map(&:to_s).join(', ') if errors.kind_of?(Array)
68
+ msg = "#{msg} | Errors: #{errors.to_s}"
69
+ end
70
+
71
+ msg
72
+ end
73
+ end
74
+ end
@@ -1,13 +1,62 @@
1
+ # Rapidash::TestClient
2
+ # A dummy client for testing with. Create a new test
3
+ # client by including this module and initializing
4
+ # with a set of responses.
5
+ # Example:
6
+ #
7
+ # class TesterClient
8
+ # include Rapidash::TestClient
9
+ # end
10
+ #
11
+ # responses = {
12
+ # get: { "foo" => "bar" },
13
+ # post: { "baz" => "data" }
14
+ # }
15
+ #
16
+ # client = TesterClient.new(responses)
17
+ #
18
+ # Example with JSON support:
19
+ #
20
+ # responses = {
21
+ # get: { "foo" => '{"some": 123, "json": 456}' }
22
+ # }
23
+ #
24
+ # client = TesterClient.new(responses, json: true)
1
25
  module Rapidash
2
26
  module TestClient
3
- attr_accessor :responses
27
+ attr_reader :responses, :stubs, :json
4
28
 
5
- def initialize(options = {})
6
- @responses = options.delete(:responses)
29
+ def initialize(responses, options = {})
30
+ @json = options[:json] || false
31
+ @responses = responses
32
+ build_stubs
7
33
  end
8
34
 
9
35
  def request(verb, url, options = {})
10
- Response.new(responses[verb][url])
36
+ connection.send(verb, url, options).body
37
+ end
38
+
39
+ private
40
+
41
+ def build_stubs
42
+ @stubs = Faraday::Adapter::Test::Stubs.new do |stub|
43
+ responses.each_pair do |verb, req|
44
+ req.each_pair do |url, body|
45
+ stub.send(verb, url) { [200, {}, body] }
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def connection
52
+ @connection ||= Faraday.new do |builder|
53
+ builder.adapter :test, stubs
54
+ builder.use FaradayMiddleware::Mashify
55
+
56
+ if json
57
+ builder.use FaradayMiddleware::ParseJson
58
+ end
59
+ end
11
60
  end
12
61
  end
13
62
  end
@@ -1,3 +1,3 @@
1
1
  module Rapidash
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0.beta"
3
3
  end
data/lib/rapidash.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  #Required for pluralization and camelcasing
2
2
  require "active_support/core_ext/string"
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+ require "json"
3
5
 
4
6
  require "rapidash/version"
5
7
 
6
- require "rapidash/errors"
7
-
8
- require "rapidash/response"
8
+ require "faraday/response/raise_rapidash_error"
9
+ require "rapidash/response_error"
9
10
 
10
11
  require "rapidash/resourceable"
11
12
  require "rapidash/client"
@@ -18,4 +19,7 @@ require "rapidash/oauth_client"
18
19
  require "rapidash/test_client"
19
20
 
20
21
  module Rapidash
22
+ mattr_accessor :response_exception_class
23
+
24
+ class ConfigurationError < StandardError; end
21
25
  end
data/rapidash.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rapidash/version'
4
+ require "rapidash/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "rapidash"
@@ -22,11 +22,16 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec", "~> 2.8"
24
24
  spec.add_development_dependency "simplecov", "~> 0.7"
25
+ spec.add_development_dependency "json"
25
26
 
26
- spec.add_dependency 'json'
27
- spec.add_dependency 'faraday', '~> 0.8'
27
+ spec.add_dependency "faraday", "~> 0.8"
28
+ spec.add_dependency "faraday_middleware", "~> 0.9"
29
+ spec.add_dependency "faraday_middleware-multi_json", "~> 0.0"
28
30
  spec.add_dependency "oauth2", "~>0.6"
29
31
  spec.add_dependency "hashie", "~>1.2"
30
- spec.add_dependency "activesupport", "~>3.0"
31
-
32
+ if RUBY_VERSION < "1.9.3"
33
+ spec.add_dependency "activesupport", "~> 3.0"
34
+ else
35
+ spec.add_dependency "activesupport", ">= 3.0.0"
36
+ end
32
37
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Faraday::Response::RaiseRapidashError do
4
+ context "successful response" do
5
+ let(:env) { { :status => '200' } }
6
+
7
+ it "should not raise an exception" do
8
+ expect {
9
+ subject.on_complete(env)
10
+ }.to_not raise_exception(Rapidash::ResponseError)
11
+ end
12
+ end
13
+
14
+ context "error response" do
15
+ let(:env) { { :status => '404', :method => 'post', :url => 'http://acme.com/api/posts' } }
16
+
17
+ it "should raise an exception" do
18
+ expect {
19
+ subject.on_complete(env)
20
+ }.to raise_exception(Rapidash::ResponseError)
21
+ end
22
+
23
+ describe "custom reponse error" do
24
+ before :each do
25
+ class MyCustomResponseError < Rapidash::ResponseError; end
26
+ Rapidash.response_exception_class = MyCustomResponseError
27
+ end
28
+
29
+ it "should raise a custom excpetion class if specified" do
30
+ expect {
31
+ subject.on_complete(env)
32
+ }.to raise_exception(MyCustomResponseError)
33
+ end
34
+
35
+ after :each do
36
+ Rapidash.response_exception_class = nil
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,10 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- class Client < Rapidash::Client
4
- method :test
5
- end
6
-
7
-
8
3
  class OAuthClientTester < Rapidash::Client
9
4
  method :oauth
10
5
  end
@@ -25,13 +20,13 @@ class HTTPClientErrorTester < HTTPClientTester
25
20
  raise_errors
26
21
  end
27
22
 
28
- class TestClientTester
23
+ class TestClientTester < Rapidash::Client
29
24
  method :test
30
25
  end
31
26
 
32
27
  describe Rapidash::Client do
33
28
 
34
- let!(:subject) { Client.new }
29
+ let(:test_client) { TestClientTester.new({}) }
35
30
 
36
31
  describe "#method" do
37
32
  it "should include the HTTPClient" do
@@ -45,8 +40,7 @@ describe Rapidash::Client do
45
40
  end
46
41
 
47
42
  it "should include the OAuthClient" do
48
- client = TestClientTester.new
49
- client.class.ancestors.should include(Rapidash::TestClient)
43
+ test_client.class.ancestors.should include(Rapidash::TestClient)
50
44
  end
51
45
 
52
46
  it "should raise an error on anything else" do
@@ -85,61 +79,75 @@ describe Rapidash::Client do
85
79
 
86
80
  describe ".site=" do
87
81
  it "should clear the connection variable after set new site" do
88
- subject.instance_variable_get(:@connection).should eql(nil)
89
- subject.site = "foo"
90
- subject.instance_variable_set(:@connection, "Not nil")
82
+ test_client.instance_variable_get(:@connection).should eql(nil)
83
+ test_client.site = "foo"
84
+ test_client.instance_variable_set(:@connection, "Not nil")
91
85
 
92
- subject.site = "bar"
93
- subject.instance_variable_get(:@connection).should eql(nil)
86
+ test_client.site = "bar"
87
+ test_client.instance_variable_get(:@connection).should eql(nil)
94
88
  end
95
89
 
96
90
  it "should set the site variable" do
97
- subject.instance_variable_get(:@site).should eql(nil)
98
- subject.site = "foo"
99
- subject.instance_variable_get(:@site).should eql("foo")
91
+ test_client.instance_variable_get(:@site).should eql(nil)
92
+ test_client.site = "foo"
93
+ test_client.instance_variable_get(:@site).should eql("foo")
100
94
  end
101
95
  end
102
96
 
97
+ describe ".encode_request_with" do
98
+ let(:klass) { test_client.class }
99
+
100
+ it "should set encoder for valid argument" do
101
+ klass.encode_request_with(:json)
102
+ expect(klass.encoder).to eq :json
103
+ end
104
+
105
+ it "should raise exception for invalid argument" do
106
+ expect {
107
+ klass.encode_request_with(:wibble)
108
+ }.to raise_exception(ArgumentError)
109
+ end
110
+ end
103
111
 
104
112
  describe ".get" do
105
113
  it "should call request" do
106
- subject.should_receive(:request).with(:get, "foo", {})
107
- subject.get("foo")
114
+ test_client.should_receive(:request).with(:get, "foo", {})
115
+ test_client.get("foo")
108
116
  end
109
117
  end
110
118
 
111
119
  describe ".post" do
112
120
  it "should call request" do
113
- subject.should_receive(:request).with(:post, "foo", {})
114
- subject.post("foo")
121
+ test_client.should_receive(:request).with(:post, "foo", {})
122
+ test_client.post("foo")
115
123
  end
116
124
  end
117
125
 
118
126
  describe ".put" do
119
127
  it "should call request" do
120
- subject.should_receive(:request).with(:put, "foo", {})
121
- subject.put("foo")
128
+ test_client.should_receive(:request).with(:put, "foo", {})
129
+ test_client.put("foo")
122
130
  end
123
131
  end
124
132
 
125
133
  describe ".patch" do
126
134
  it "should call request" do
127
- subject.should_receive(:request).with(:patch, "foo", {})
128
- subject.patch("foo")
135
+ test_client.should_receive(:request).with(:patch, "foo", {})
136
+ test_client.patch("foo")
129
137
  end
130
138
  end
131
139
 
132
140
  describe ".delete" do
133
141
  it "should call request" do
134
- subject.should_receive(:request).with(:delete, "foo", {})
135
- subject.delete("foo")
142
+ test_client.should_receive(:request).with(:delete, "foo", {})
143
+ test_client.delete("foo")
136
144
  end
137
145
  end
138
146
 
139
147
  describe ".normalize_url" do
140
148
  it "should use the instance extension if set" do
141
- subject.extension = :json
142
- subject.normalize_url("users").should eql("users.json")
149
+ test_client.extension = :json
150
+ test_client.normalize_url("users").should eql("users.json")
143
151
  end
144
152
 
145
153
  it "should use the class extension if set" do
@@ -147,7 +155,7 @@ describe Rapidash::Client do
147
155
  end
148
156
 
149
157
  it "should return the url if no extension if set" do
150
- subject.normalize_url("users").should eql("users")
158
+ test_client.normalize_url("users").should eql("users")
151
159
  end
152
160
  end
153
161
  end
@@ -46,64 +46,25 @@ describe Rapidash::HTTPClient do
46
46
  end
47
47
 
48
48
  describe "authorization" do
49
- let!(:options) { { :login => "login", :password => "password" } }
50
- let!(:subject) { HTTPTester.new(options) }
49
+ let!(:subject) { HTTPTester.new(:login => "login", :password => "password") }
51
50
 
52
- it "should authorize with login and password" do
53
- subject.should_receive(:process_response).with("response", :get, {})
54
- subject.connection.should_receive(:basic_auth).with(options[:login], options[:password])
55
- subject.connection.stub_chain('app.call').and_return("response")
56
- subject.request(:get, "foo")
51
+ it "should delegate to Faraday's basic auth" do
52
+ expect(subject.connection.builder.handlers).to include(Faraday::Request::BasicAuthentication)
57
53
  end
58
54
  end
59
55
 
60
- it "should call response" do
61
- subject.should_receive(:process_response).with("response", :get, {})
62
- subject.connection.should_receive(:run_request).with(:get, "http://example.com/foo", nil, nil).and_return("response")
63
- subject.request(:get, "foo")
64
- end
65
- end
66
-
67
- describe ".process_response" do
68
-
69
- let!(:valid_response) { OpenStruct.new(:status => "200")}
70
- let!(:redirect_response) { OpenStruct.new(:status => "301", :headers => {"location" => "http://example.com/redirect"})}
71
- let!(:error_response) { OpenStruct.new(:status => "404")}
72
-
73
- before(:each) do
74
- subject.site = "http://example.com"
75
- end
56
+ describe "without authorization" do
57
+ let!(:subject) { HTTPTester.new() }
76
58
 
77
- describe "valid response" do
78
- before(:each) do
79
- Rapidash::Response.should_receive(:new).and_return("response")
80
- end
81
-
82
- it "should return a response object" do
83
- response = subject.process_response(valid_response, :get, {})
84
- response.should eql("response")
85
- end
86
-
87
- it "should perform a redirect" do
88
- subject.should_receive(:request).with(:get, "http://example.com/redirect", anything).and_return(subject.process_response(valid_response, :get, {}))
89
- response = subject.process_response(redirect_response, :get, {})
90
- response.should eql("response")
59
+ it "should delegate to Faraday's basic auth" do
60
+ expect(subject.connection.builder.handlers).to_not include(Faraday::Request::BasicAuthentication)
91
61
  end
92
62
  end
93
63
 
94
- describe "error response" do
95
- it "should not raise an error by default" do
96
- response = subject.process_response(error_response, :get, {})
97
- response.should be_nil
98
- end
99
-
100
- it "should raise an error if the option is set" do
101
- subject = HTTPErrorTester.new
102
- expect {
103
- response = subject.process_response(error_response, :get, {})
104
- }.to raise_error(Rapidash::ResponseError)
105
- end
106
-
64
+ it "should call response" do
65
+ response = double(:body => "response")
66
+ subject.connection.should_receive(:run_request).with(:get, "http://example.com/foo", nil, nil).and_return(response)
67
+ subject.request(:get, "foo")
107
68
  end
108
69
  end
109
70
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Integration
4
-
5
4
  class Repo < Rapidash::Base
6
5
  end
7
6
 
@@ -14,29 +13,17 @@ module Integration
14
13
  method :test
15
14
  resource :users
16
15
  end
17
-
18
16
  end
19
17
 
20
- gazler = OpenStruct.new({
21
- :headers => { "content-type" => "application/json" },
22
- :body => { :name => "Gary Rennie" }.to_json
23
- })
24
-
25
- repos = OpenStruct.new({
26
- :headers => { "content-type" => "application/json" },
27
- :body => [ { :name => "Githug" } ].to_json
28
- })
29
-
30
18
  responses = {
31
19
  :get => {
32
- "members/Gazler" => gazler,
33
- "members/Gazler/repos" => repos,
20
+ "members/Gazler" => { :name => "Gary Rennie" }.to_json,
21
+ "members/Gazler/repos" => [{ :name => "Githug" }].to_json,
34
22
  }
35
23
  }
36
24
 
37
25
  describe "An actual Rapidash Client" do
38
-
39
- let!(:client) { Integration::Client.new(:responses => responses) }
26
+ let(:client) { Integration::Client.new(responses, :json => true) }
40
27
 
41
28
  it "should get the user from the API" do
42
29
  client.users!("Gazler").name.should eql("Gary Rennie")
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- class OAuthTester
3
+ class OAuthTester < Rapidash::Client
4
4
  include Rapidash::OAuthClient
5
5
  end
6
6
 
@@ -11,11 +11,6 @@ class OAuthErrorTester < OAuthTester
11
11
  end
12
12
 
13
13
  describe Rapidash::OAuthClient do
14
-
15
- before(:each) do
16
- Rapidash::Response.stub(:new).and_return(Hashie::Mash.new)
17
- end
18
-
19
14
  let(:options) {
20
15
  {
21
16
  :uid => "foo",
@@ -67,45 +62,19 @@ describe Rapidash::OAuthClient do
67
62
  end
68
63
 
69
64
  describe ".request" do
70
-
71
- let(:request) { mock }
65
+ let(:request) { mock(:body => 'data') }
72
66
 
73
67
  describe "object returned from API call" do
74
-
75
68
  before(:each) do
76
69
  subject.stub(:oauth_access_token).and_return(request)
77
70
  subject.stub(:normalize_url).with("me").and_return("me")
78
- request.stub(:get)
71
+ request.stub(:get) { request }
79
72
  end
80
73
 
81
74
  it "should return a Hashie::Mash" do
82
- subject.request(:get, "me").class.should eql(Hashie::Mash)
83
- end
84
-
85
- end
86
-
87
- describe "when errors are set" do
88
- it "should call oauth_access_token.send with errors set" do
89
- subject = OAuthErrorTester.new(options)
90
- subject.stub(:normalize_url).and_return("error")
91
- subject.stub(:oauth_access_token).and_return(request)
92
- request.should_receive(:send).with(:get, "http://example.com/error", {:raise_errors => true})
93
- subject.request(:get, "error")
94
- end
95
-
96
- end
97
-
98
- describe "when a body is set" do
99
- it "should call oauth_access_token.send with errors set" do
100
- subject.stub(:normalize_url).and_return("users")
101
- subject.stub(:oauth_access_token).and_return(request)
102
- request.should_receive(:send).with(:get, "http://example.com/users", {:body => {"foo" => "bar"}.to_json, :raise_errors => false})
103
- subject.request(:get, "error", :body => {"foo" => "bar"})
75
+ subject.request(:get, "me").should eq 'data'
104
76
  end
105
-
106
77
  end
107
-
108
-
109
78
  end
110
79
  end
111
80
 
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ class MyCustomResponseError < Rapidash::ResponseError
4
+ def errors
5
+ if body.kind_of?(Array)
6
+ body.join(', ')
7
+ else
8
+ body
9
+ end
10
+ end
11
+ end
12
+
13
+ describe Rapidash::ResponseError do
14
+
15
+ context "standard response error class" do
16
+ let(:response) { Rapidash::ResponseError.new(env) }
17
+ let(:env) { { :status => '404', :method => 'post', :url => 'http://acme.com/api/posts', :body => 'Page not found' } }
18
+
19
+ describe ".initialize" do
20
+ it "should set attributes" do
21
+ expect(response.status).to eq 404
22
+ expect(response.method).to eq 'POST'
23
+ expect(response.url).to eq 'http://acme.com/api/posts'
24
+ expect(response.body).to eq 'Page not found'
25
+ end
26
+ end
27
+
28
+ describe "#message" do
29
+ it "should create a formatted error message" do
30
+ message = response.send(:message)
31
+ expect(message).to eq '404 POST http://acme.com/api/posts'
32
+ end
33
+ end
34
+ end
35
+
36
+ context "custom error class with #errors method" do
37
+ before :each do
38
+ Rapidash.response_exception_class = MyCustomResponseError
39
+ end
40
+
41
+ let(:response) { MyCustomResponseError.new(env) }
42
+ let(:env) { { :status => '404', :method => 'post', :url => 'http://acme.com/api/posts', :body => ['name cannot be blank', 'content cannot be blank'] } }
43
+
44
+ it "should call #errors" do
45
+ response.should_receive(:errors)
46
+ response.send(:message)
47
+ end
48
+
49
+ it "should create a formatted error message" do
50
+ message = response.send(:message)
51
+ expect(message).to eq '404 POST http://acme.com/api/posts | Errors: name cannot be blank, content cannot be blank'
52
+ end
53
+
54
+ after :each do
55
+ Rapidash.response_exception_class = nil
56
+ end
57
+
58
+ end
59
+ end
@@ -1,26 +1,29 @@
1
1
  require "spec_helper"
2
2
 
3
- class TestClientTester
3
+ class TesterClient
4
4
  include Rapidash::TestClient
5
5
  end
6
6
 
7
- describe Rapidash::HTTPClient do
7
+ describe Rapidash::TestClient do
8
+ let(:responses) do
9
+ { :get => { "foo" => "bar" } }
10
+ end
8
11
 
9
- let!(:responses) {
10
- {
11
- :get => {
12
- "foo" => "response"
13
- }
14
- }
15
- }
12
+ let(:client) { TesterClient.new(responses) }
16
13
 
17
- let!(:subject) { TestClientTester.new(:responses => responses) }
14
+ describe ".new" do
15
+ let(:stubs) { client.stubs }
18
16
 
19
- describe ".request" do
20
- it "should do something" do
21
- Rapidash::Response.should_receive(:new).with("response")
22
- subject.request(:get, "foo")
17
+ it "should create Faraday test stubs" do
18
+ expect(stubs).to be_a Faraday::Adapter::Test::Stubs
23
19
  end
24
20
  end
25
21
 
22
+ describe "#request" do
23
+ let(:response) { client.request(:get, '/foo') }
24
+
25
+ it "should respond with the correct data" do
26
+ expect(response).to eq 'bar'
27
+ end
28
+ end
26
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapidash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gary 'Gazler' Rennie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-26 00:00:00.000000000 Z
11
+ date: 2013-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,7 +73,7 @@ dependencies:
73
73
  - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :runtime
76
+ type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday_middleware
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faraday_middleware-multi_json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '0.0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: oauth2
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -126,16 +154,16 @@ dependencies:
126
154
  name: activesupport
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
- - - ~>
157
+ - - '>='
130
158
  - !ruby/object:Gem::Version
131
- version: '3.0'
159
+ version: 3.0.0
132
160
  type: :runtime
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
- - - ~>
164
+ - - '>='
137
165
  - !ruby/object:Gem::Version
138
- version: '3.0'
166
+ version: 3.0.0
139
167
  description: Evolve your API
140
168
  email:
141
169
  - gazler@gmail.com
@@ -151,25 +179,26 @@ files:
151
179
  - README.md
152
180
  - Rakefile
153
181
  - examples/github.rb
182
+ - lib/faraday/response/raise_rapidash_error.rb
154
183
  - lib/rapidash.rb
155
184
  - lib/rapidash/base.rb
156
185
  - lib/rapidash/client.rb
157
- - lib/rapidash/errors.rb
158
186
  - lib/rapidash/http_client.rb
159
187
  - lib/rapidash/oauth_client.rb
160
188
  - lib/rapidash/resourceable.rb
161
- - lib/rapidash/response.rb
189
+ - lib/rapidash/response_error.rb
162
190
  - lib/rapidash/test_client.rb
163
191
  - lib/rapidash/urlable.rb
164
192
  - lib/rapidash/version.rb
165
193
  - rapidash.gemspec
194
+ - spec/faraday/raise_rapidash_error_spec.rb
166
195
  - spec/rapidash/base_spec.rb
167
196
  - spec/rapidash/client_spec.rb
168
197
  - spec/rapidash/http_client_spec.rb
169
198
  - spec/rapidash/integration/test_client_spec.rb
170
199
  - spec/rapidash/oauth_client_spec.rb
171
200
  - spec/rapidash/resourceable_spec.rb
172
- - spec/rapidash/response_spec.rb
201
+ - spec/rapidash/response_error_spec.rb
173
202
  - spec/rapidash/test_client_spec.rb
174
203
  - spec/rapidash/urlable_spec.rb
175
204
  - spec/spec_helper.rb
@@ -188,23 +217,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
217
  version: '0'
189
218
  required_rubygems_version: !ruby/object:Gem::Requirement
190
219
  requirements:
191
- - - '>='
220
+ - - '>'
192
221
  - !ruby/object:Gem::Version
193
- version: '0'
222
+ version: 1.3.1
194
223
  requirements: []
195
224
  rubyforge_project:
196
- rubygems_version: 2.0.0
225
+ rubygems_version: 2.0.2
197
226
  signing_key:
198
227
  specification_version: 4
199
228
  summary: An opinionated core for creating clients for RESTful APIs quickly
200
229
  test_files:
230
+ - spec/faraday/raise_rapidash_error_spec.rb
201
231
  - spec/rapidash/base_spec.rb
202
232
  - spec/rapidash/client_spec.rb
203
233
  - spec/rapidash/http_client_spec.rb
204
234
  - spec/rapidash/integration/test_client_spec.rb
205
235
  - spec/rapidash/oauth_client_spec.rb
206
236
  - spec/rapidash/resourceable_spec.rb
207
- - spec/rapidash/response_spec.rb
237
+ - spec/rapidash/response_error_spec.rb
208
238
  - spec/rapidash/test_client_spec.rb
209
239
  - spec/rapidash/urlable_spec.rb
210
240
  - spec/spec_helper.rb
@@ -1,5 +0,0 @@
1
- module Rapidash
2
- class ParseError < StandardError; end
3
- class ConfigurationError < StandardError; end
4
- class ResponseError < StandardError; end
5
- end
@@ -1,29 +0,0 @@
1
- require 'json'
2
- require 'hashie'
3
-
4
- module Rapidash
5
- class Response
6
- class << self
7
- def new(response)
8
- return nil unless response.body
9
- return nil if response.body.empty?
10
- return nil if response.body == "null"
11
- type = response.headers["content-type"]
12
- body = JSON.parse(response.body)
13
- if body.kind_of?(Hash)
14
- return Hashie::Mash.new(body)
15
- elsif body.kind_of?(Array)
16
- output = []
17
- body.each do |el|
18
- output << Hashie::Mash.new(el)
19
- end
20
- return output
21
- end
22
- rescue JSON::ParserError => e
23
- raise ParseError.new("Failed to parse content for type: #{type}")
24
- end
25
- end
26
-
27
- end
28
- end
29
-
@@ -1,145 +0,0 @@
1
- require 'json'
2
- require "spec_helper"
3
-
4
- def valid_response_object
5
- body = {"foo" => "bar" }.to_json
6
- OpenStruct.new({
7
- :headers => {
8
- "content-type" => "application/json"
9
- },
10
- :body => body
11
- })
12
- end
13
-
14
- def valid_html_response_object
15
- body = {"foo" => "bar" }.to_json
16
- OpenStruct.new({
17
- :headers => {
18
- "content-type" => "text/html"
19
- },
20
- :body => body
21
- })
22
- end
23
-
24
- def valid_js_response_object
25
- body = {"foo" => "bar" }.to_json
26
- OpenStruct.new({
27
- :headers => {
28
- "content-type" => "text/javascript"
29
- },
30
- :body => body
31
- })
32
- end
33
-
34
- def valid_null_response_object
35
- body = nil.to_json
36
- OpenStruct.new({
37
- :headers => {
38
- "content-type" => "application/json"
39
- },
40
- :body => body
41
- })
42
- end
43
-
44
- def valid_empty_response_object
45
- body = ""
46
- OpenStruct.new({
47
- :headers => {
48
- "content-type" => "application/json"
49
- },
50
- :body => body
51
- })
52
- end
53
-
54
-
55
- def valid_response_array
56
- body = [{"foo" => "bar" }, {"baz" => "bra"}].to_json
57
- OpenStruct.new({
58
- :headers => {
59
- "content-type" => "application/json"
60
- },
61
- :body => body
62
- })
63
- end
64
-
65
-
66
- def invalid_response
67
- OpenStruct.new({
68
- :headers => {
69
- "content-type" => "application/xml"
70
- },
71
- :body => "<xml>something</xml>"
72
- })
73
- end
74
-
75
- def invalid_js_response_object
76
- OpenStruct.new({
77
- :headers => {
78
- "content-type" => "text/javascript"
79
- },
80
- :body => "<xml>something</xml>"
81
- })
82
- end
83
-
84
- def nil_response
85
- OpenStruct.new({
86
- :body => nil
87
- })
88
- end
89
-
90
- describe Rapidash::Response do
91
-
92
- describe "#new" do
93
- it "should parse JSON Objects" do
94
- response = Rapidash::Response.new(valid_response_object)
95
- response.foo.should eql("bar")
96
- end
97
-
98
- it "should parse JSON Objects returned with javascript type" do
99
- response = Rapidash::Response.new(valid_js_response_object)
100
- response.foo.should eql("bar")
101
- end
102
-
103
- it "should parse JSON Objects returned with html type" do
104
- response = Rapidash::Response.new(valid_html_response_object)
105
- response.foo.should eql("bar")
106
- end
107
-
108
- it "should parse a JSON null" do
109
- response = Rapidash::Response.new(valid_null_response_object)
110
- response.should eql(nil)
111
- end
112
-
113
- it "should parse an empty body" do
114
- response = Rapidash::Response.new(valid_empty_response_object)
115
- response.should eql(nil)
116
- end
117
-
118
-
119
- it "should parse JSON Arrays" do
120
- response = Rapidash::Response.new(valid_response_array)
121
- response[0].foo.should eql("bar")
122
- response[1].baz.should eql("bra")
123
- end
124
-
125
- it "should return nil if the response has no body" do
126
- response = Rapidash::Response.new(nil_response)
127
- response.should eql(nil)
128
- end
129
-
130
-
131
- it "should raise an error on a non-json response" do
132
- expect {
133
- Rapidash::Response.new(invalid_response)
134
- }.to raise_error(Rapidash::ParseError)
135
- end
136
-
137
- it "should raise an error on a non-json response body" do
138
- expect {
139
- Rapidash::Response.new(invalid_js_response_object)
140
- }.to raise_error(Rapidash::ParseError)
141
- end
142
- end
143
-
144
-
145
- end