jeffersongirao_faraday-stack 0.1.5

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.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # Über Stack
2
+
3
+ [Faraday][] is an HTTP client lib that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle.
4
+
5
+ *“Faraday Stack”* is an add-on library that implements several middleware (such as JSON and XML parsers) and helps you build an awesome stack that covers most of your API-consuming needs.
6
+
7
+ Boring example:
8
+
9
+ require 'faraday_stack'
10
+
11
+ response = FaradayStack.get 'http://google.com'
12
+
13
+ response.headers['content-type'] #=> "text/html; charset=UTF-8"
14
+ response.headers['location'] #=> "http://www.google.com/"
15
+ puts response.body
16
+
17
+ Awesome example:
18
+
19
+ conn = FaradayStack.build 'http://github.com/api/v2'
20
+
21
+ # JSON resource
22
+ resp = conn.get 'json/repos/show/mislav/faraday-stack'
23
+ resp.body
24
+ #=> {"repository"=>{"language"=>"Ruby", "fork"=>false, ...}}
25
+
26
+ # XML resource
27
+ resp = conn.get 'xml/repos/show/mislav/faraday-stack'
28
+ resp.body.class
29
+ #=> Nokogiri::XML::Document
30
+
31
+ # 404
32
+ conn.get 'zomg/wrong/url'
33
+ #=> raises Faraday::Error::ResourceNotFound
34
+
35
+ ## Features
36
+
37
+ * parses JSON, XML & HTML
38
+ * raises exceptions on 4xx, 5xx responses
39
+ * follows redirects
40
+
41
+ To see how the default stack is built, see "[faraday_stack.rb][source]".
42
+
43
+ ### Optional features:
44
+
45
+ * encode POST/PUT bodies as JSON:
46
+
47
+ conn.post(path, payload, :content_type => 'application/json')
48
+
49
+ * add `Instrumentation` middleware to instrument requests with ActiveSupport
50
+
51
+ conn.builder.insert_after Faraday::Response::RaiseError, FaradayStack::Instrumentation
52
+
53
+ * add `Caching` middleware to have GET responses cached
54
+
55
+ conn.builder.insert_before FaradayStack::ResponseJSON, FaradayStack::Caching do
56
+ ActiveSupport::Cache::FileStore.new 'tmp/cache',
57
+ :namespace => 'faraday', :expires_in => 3600
58
+ end
59
+
60
+ * mount [Rack::Cache][] through `RackCompatible` middleware for HTTP caching of responses
61
+
62
+ conn.builder.insert_after FaradayStack::FollowRedirects, FaradayStack::RackCompatible,
63
+ Rack::Cache::Context,
64
+ :metastore => "file:/var/cache/rack/meta",
65
+ :entitystore => "file:/var/cache/rack/body"
66
+
67
+
68
+ [faraday]: https://github.com/technoweenie/faraday
69
+ [source]: https://github.com/mislav/faraday-stack/blob/master/lib/faraday_stack.rb
70
+ [rack::cache]: http://rtomayko.github.com/rack-cache/
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.pattern = 'test/**/*_test.rb'
9
+ test.verbose = true
10
+ end
@@ -0,0 +1 @@
1
+ require 'faraday_stack'
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ require 'faraday'
3
+ require 'forwardable'
4
+ require 'faraday_stack/addressable_patch'
5
+
6
+ module FaradayStack
7
+ extend Faraday::AutoloadHelper
8
+
9
+ autoload_all 'faraday_stack',
10
+ :ResponseMiddleware => 'response_middleware',
11
+ :ResponseJSON => 'response_json',
12
+ :ResponseXML => 'response_xml',
13
+ :ResponseHTML => 'response_html',
14
+ :Instrumentation => 'instrumentation',
15
+ :Caching => 'caching',
16
+ :FollowRedirects => 'follow_redirects',
17
+ :RackCompatible => 'rack_compatible'
18
+
19
+ # THE ÜBER STACK
20
+ def self.default_connection
21
+ @default_connection ||= self.build
22
+ end
23
+
24
+ class << self
25
+ extend Forwardable
26
+ attr_writer :default_connection
27
+ def_delegators :default_connection, :get, :post, :put, :head, :delete
28
+ end
29
+
30
+ def self.build(url = nil, options = {})
31
+ klass = nil
32
+ if url.is_a?(Hash) then options = url.dup
33
+ elsif url.is_a?(Class) then klass = url
34
+ else options = options.merge(:url => url)
35
+ end
36
+
37
+ klass ||= options.delete(:class) || Faraday::Connection
38
+
39
+ klass.new(options) do |builder|
40
+ builder.request :url_encoded
41
+ builder.request :json
42
+ yield builder if block_given?
43
+ builder.use ResponseXML, :content_type => /[+\/]xml$/
44
+ builder.use ResponseHTML, :content_type => 'text/html'
45
+ builder.use ResponseJSON, :content_type => /[+\/]json$/
46
+ builder.use ResponseJSON::MimeTypeFix, :content_type => /text\/(plain|javascript)/
47
+ builder.use FollowRedirects
48
+ builder.response :raise_error
49
+ builder.adapter Faraday.default_adapter
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,20 @@
1
+ require 'addressable/uri'
2
+
3
+ # feature-detect the bug
4
+ unless Addressable::URI.parse('/?a=1&b=2') === '/?b=2&a=1'
5
+ # fix `normalized_query` by sorting query key-value pairs
6
+ # (rejected: https://github.com/sporkmonger/addressable/issues/28)
7
+ class Addressable::URI
8
+ alias normalized_query_without_ordering_fix normalized_query
9
+
10
+ def normalized_query
11
+ fresh = @normalized_query.nil?
12
+ query = normalized_query_without_ordering_fix
13
+ if query && fresh
14
+ @normalized_query = query.split('&', -1).sort_by {|q| q[0..(q.index('=')||-1)] }.join('&')
15
+ else
16
+ query
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,55 @@
1
+ module FaradayStack
2
+ class Caching < Faraday::Middleware
3
+ attr_reader :cache
4
+
5
+ def initialize(app, cache = nil, options = {})
6
+ super(app)
7
+ @cache = cache || Proc.new.call
8
+ @options = options
9
+ end
10
+
11
+ def call(env)
12
+ if :get == env[:method]
13
+ if env[:parallel_manager]
14
+ # callback mode
15
+ cache_on_complete(env)
16
+ else
17
+ # synchronous mode
18
+ response = cache.fetch(cache_key(env)) { @app.call(env) }
19
+ finalize_response(response, env)
20
+ end
21
+ else
22
+ @app.call(env)
23
+ end
24
+ end
25
+
26
+ def cache_key(env)
27
+ url = env[:url].dup
28
+ if url.query && params_to_strip.any?
29
+ url.query_values = url.query_values.reject { |k,| params_to_strip.include? k }
30
+ end
31
+ url.normalize!
32
+ url.request_uri
33
+ end
34
+
35
+ def params_to_strip
36
+ @params_to_strip ||= Array(@options[:strip_params]).map { |p| p.to_s }
37
+ end
38
+
39
+ def cache_on_complete(env)
40
+ key = cache_key(env)
41
+ if cached_response = cache.read(key)
42
+ finalize_response(cached_response, env)
43
+ else
44
+ response = @app.call(env)
45
+ response.on_complete { cache.write(key, response) }
46
+ end
47
+ end
48
+
49
+ def finalize_response(response, env)
50
+ response = env[:response] = response.dup if response.frozen?
51
+ response.apply_request env unless response.env[:method]
52
+ response
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,42 @@
1
+ module FaradayStack
2
+ class RedirectLimitReached < Faraday::Error::ClientError
3
+ attr_reader :response
4
+
5
+ def initialize(response)
6
+ super "too many redirects; last one to: #{response['location']}"
7
+ @response = response
8
+ end
9
+ end
10
+
11
+ class FollowRedirects < Faraday::Middleware
12
+ REDIRECTS = [301, 302, 303, 307]
13
+ # default value for max redirects followed
14
+ FOLLOW_LIMIT = 3
15
+
16
+ def initialize(app, options = {})
17
+ super(app)
18
+ @options = options
19
+ @follow_limit = options[:limit] || FOLLOW_LIMIT
20
+ end
21
+
22
+ def call(env)
23
+ process_response(@app.call(env), @follow_limit)
24
+ end
25
+
26
+ def process_response(response, follows)
27
+ response.on_complete do |env|
28
+ if redirect? response
29
+ raise RedirectLimitReached, response if follows.zero?
30
+ env[:url] += response['location']
31
+ env[:method] = :get
32
+ response = process_response(@app.call(env), follows - 1)
33
+ end
34
+ end
35
+ response
36
+ end
37
+
38
+ def redirect?(response)
39
+ REDIRECTS.include? response.status
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ module FaradayStack
2
+ # Measures request time only in synchronous request mode.
3
+ # Sample subscriber:
4
+ #
5
+ # ActiveSupport::Notifications.subscribe('request.faraday') do |name, start_time, end_time, _, env|
6
+ # url = env[:url]
7
+ # http_method = env[:method].to_s.upcase
8
+ # duration = end_time - start_time
9
+ # $stderr.puts '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration]
10
+ # end
11
+ class Instrumentation < Faraday::Middleware
12
+ dependency 'active_support/notifications'
13
+
14
+ def initialize(app, options = {})
15
+ super(app)
16
+ @options = options
17
+ @name = options[:name] || 'request.faraday'
18
+ end
19
+
20
+ def call(env)
21
+ ActiveSupport::Notifications.instrument(@name, env) do
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,76 @@
1
+ require 'stringio'
2
+
3
+ module FaradayStack
4
+ # Wraps a handler originally written for Rack to make it compatible with Faraday.
5
+ #
6
+ # Experimental. Only handles changes in request headers.
7
+ class RackCompatible
8
+ def initialize(app, rack_handler, *args)
9
+ # tiny middleware that decomposes a Faraday::Response to standard Rack
10
+ # array: [status, headers, body]
11
+ compatible_app = lambda do |env|
12
+ restore_env(env)
13
+ response = app.call(env)
14
+ [response.status, response.headers, Array(response.body)]
15
+ end
16
+ @rack = rack_handler.new(compatible_app, *args)
17
+ end
18
+
19
+ def call(env)
20
+ prepare_env(env)
21
+ rack_response = @rack.call(env)
22
+ finalize_response(env, rack_response)
23
+ end
24
+
25
+ NonPrefixedHeaders = %w[CONTENT_LENGTH CONTENT_TYPE]
26
+
27
+ # faraday to rack-compatible
28
+ def prepare_env(env)
29
+ env[:request_headers].each do |name, value|
30
+ name = name.upcase.tr('-', '_')
31
+ name = "HTTP_#{name}" unless NonPrefixedHeaders.include? name
32
+ env[name] = value
33
+ end
34
+
35
+ url = env[:url]
36
+ env['rack.url_scheme'] = url.scheme
37
+ env['PATH_INFO'] = url.path
38
+ env['SERVER_PORT'] = url.inferred_port
39
+ env['QUERY_STRING'] = url.query
40
+ env['REQUEST_METHOD'] = env[:method].to_s.upcase
41
+
42
+ env['rack.errors'] ||= StringIO.new
43
+
44
+ env
45
+ end
46
+
47
+ # rack to faraday-compatible
48
+ def restore_env(env)
49
+ headers = env[:request_headers]
50
+ headers.clear
51
+
52
+ env.each do |name, value|
53
+ next unless String === name
54
+ if NonPrefixedHeaders.include? name or name.index('HTTP_') == 0
55
+ name = name.sub(/^HTTP_/, '').downcase.tr('_', '-')
56
+ headers[name] = value
57
+ end
58
+ end
59
+
60
+ env[:method] = env['REQUEST_METHOD'].downcase.to_sym
61
+ env
62
+ end
63
+
64
+ def finalize_response(env, rack_response)
65
+ status, headers, body = rack_response
66
+ body = body.inject('') { |str, part| str << part }
67
+ headers = Faraday::Utils::Headers.new(headers) unless Faraday::Utils::Headers === headers
68
+
69
+ response_env = { :status => status, :body => body, :response_headers => headers }
70
+
71
+ env[:response] ||= Faraday::Response.new({})
72
+ env[:response].env.update(response_env)
73
+ env[:response]
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ module FaradayStack
2
+ class ResponseHTML < ResponseMiddleware
3
+ dependency do
4
+ require 'nokogiri'
5
+ Nokogiri::HTML
6
+ end
7
+
8
+ define_parser do |body|
9
+ Nokogiri::HTML body
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,50 @@
1
+ module FaradayStack
2
+ class ResponseJSON < ResponseMiddleware
3
+ adapter_name = nil
4
+
5
+ # loads the JSON decoder either from yajl-ruby or activesupport
6
+ dependency do
7
+ require 'yajl'
8
+ adapter_name = Yajl::Parser.name
9
+ end
10
+
11
+ dependency do
12
+ require 'active_support/json/decoding'
13
+ adapter_name = ActiveSupport::JSON.name
14
+ end unless loaded?
15
+
16
+ # defines a parser block depending on which adapter has loaded
17
+ case adapter_name
18
+ when 'Yajl::Parser'
19
+ define_parser do |body|
20
+ Yajl::Parser.parse(body)
21
+ end
22
+ when 'ActiveSupport::JSON'
23
+ define_parser do |body|
24
+ unless body.nil? or body.empty?
25
+ result = ActiveSupport::JSON.decode(body)
26
+ raise ActiveSupport::JSON.backend::ParseError if String === result
27
+ result
28
+ end
29
+ end
30
+ end
31
+
32
+ # writes the correct MIME-type if the payload looks like JSON
33
+ class MimeTypeFix < ResponseMiddleware
34
+ def on_complete(env)
35
+ if process_response_type?(response_type(env)) and looks_like_json?(env)
36
+ old_type = env[:response_headers][CONTENT_TYPE]
37
+ new_type = 'application/json'
38
+ new_type << ';' << old_type.split(';', 2).last if old_type.index(';')
39
+ env[:response_headers][CONTENT_TYPE] = new_type
40
+ end
41
+ end
42
+
43
+ BRACKETS = %w- [ { -
44
+
45
+ def looks_like_json?(env)
46
+ parse_response?(env) and BRACKETS.include? env[:body][0,1]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,64 @@
1
+ module FaradayStack
2
+ # A base class for middleware that parses responses
3
+ class ResponseMiddleware < Faraday::Response::Middleware
4
+ CONTENT_TYPE = 'Content-Type'.freeze
5
+
6
+ class << self
7
+ attr_accessor :parser
8
+ end
9
+
10
+ # Stores a block that receives the body and should return a parsed result
11
+ def self.define_parser(&block)
12
+ @parser = block
13
+ end
14
+
15
+ def self.inherited(subclass)
16
+ super
17
+ subclass.load_error = self.load_error
18
+ subclass.parser = self.parser
19
+ end
20
+
21
+ def initialize(app = nil, options = {})
22
+ super(app)
23
+ @options = options
24
+ @content_types = Array(options[:content_type])
25
+ end
26
+
27
+ # Override this to modify the environment after the response has finished.
28
+ def on_complete(env)
29
+ if process_response_type?(response_type(env)) and parse_response?(env)
30
+ env[:body] = parse(env[:body])
31
+ end
32
+ end
33
+
34
+ # Parses the response body and returns the result.
35
+ # Instead of overriding this method, consider using `define_parser`
36
+ def parse(body)
37
+ if self.class.parser
38
+ begin
39
+ self.class.parser.call(body)
40
+ rescue
41
+ raise Faraday::Error::ParsingError, $!
42
+ end
43
+ else
44
+ body
45
+ end
46
+ end
47
+
48
+ def response_type(env)
49
+ type = env[:response_headers][CONTENT_TYPE].to_s
50
+ type = type.split(';', 2).first if type.index(';')
51
+ type
52
+ end
53
+
54
+ def process_response_type?(type)
55
+ @content_types.empty? or @content_types.any? { |pattern|
56
+ Regexp === pattern ? type =~ pattern : type == pattern
57
+ }
58
+ end
59
+
60
+ def parse_response?(env)
61
+ env[:body].respond_to? :to_str
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,12 @@
1
+ module FaradayStack
2
+ class ResponseXML < ResponseMiddleware
3
+ dependency do
4
+ require 'nokogiri'
5
+ Nokogiri::XML
6
+ end
7
+
8
+ define_parser do |body|
9
+ Nokogiri::XML body
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,120 @@
1
+ require 'test_helper'
2
+ require 'forwardable'
3
+ require 'fileutils'
4
+ require 'rack/cache'
5
+
6
+ class CachingTest < Test::Unit::TestCase
7
+ class TestCache < Hash
8
+ def read(key)
9
+ if cached = self[key]
10
+ Marshal.load(cached)
11
+ end
12
+ end
13
+
14
+ def write(key, data)
15
+ self[key] = Marshal.dump(data)
16
+ end
17
+
18
+ def fetch(key)
19
+ read(key) || yield.tap { |data| write(key, data) }
20
+ end
21
+ end
22
+
23
+ def setup
24
+ @cache = TestCache.new
25
+
26
+ request_count = 0
27
+ response = lambda { |env|
28
+ [200, {'Content-Type' => 'text/plain'}, "request:#{request_count+=1}"]
29
+ }
30
+
31
+ @conn = Faraday.new do |b|
32
+ b.use FaradayStack::Caching, @cache
33
+ b.adapter :test do |stub|
34
+ stub.get('/', &response)
35
+ stub.get('/?foo=bar', &response)
36
+ stub.post('/', &response)
37
+ stub.get('/other', &response)
38
+ end
39
+ end
40
+ end
41
+
42
+ extend Forwardable
43
+ def_delegators :@conn, :get, :post
44
+
45
+ def test_cache_get
46
+ assert_equal 'request:1', get('/').body
47
+ assert_equal 'request:1', get('/').body
48
+ assert_equal 'request:2', get('/other').body
49
+ assert_equal 'request:2', get('/other').body
50
+ end
51
+
52
+ def test_response_has_request_params
53
+ get('/') # make cache
54
+ response = get('/')
55
+ assert_equal :get, response.env[:method]
56
+ assert_equal '/', response.env[:url].to_s
57
+ end
58
+
59
+ def test_cache_query_params
60
+ assert_equal 'request:1', get('/').body
61
+ assert_equal 'request:2', get('/?foo=bar').body
62
+ assert_equal 'request:2', get('/?foo=bar').body
63
+ assert_equal 'request:1', get('/').body
64
+ end
65
+
66
+ def test_doesnt_cache_post
67
+ assert_equal 'request:1', post('/').body
68
+ assert_equal 'request:2', post('/').body
69
+ assert_equal 'request:3', post('/').body
70
+ end
71
+ end
72
+
73
+ # RackCompatible + Rack::Cache
74
+ class HttpCachingTest < Test::Unit::TestCase
75
+ include FileUtils
76
+
77
+ CACHE_DIR = File.expand_path('../cache', __FILE__)
78
+
79
+ def setup
80
+ rm_r CACHE_DIR if File.exists? CACHE_DIR
81
+
82
+ request_count = 0
83
+ response = lambda { |env|
84
+ [200, { 'Content-Type' => 'text/plain',
85
+ 'Cache-Control' => 'public, max-age=900',
86
+ },
87
+ "request:#{request_count+=1}"]
88
+ }
89
+
90
+ @conn = Faraday.new do |b|
91
+ b.use FaradayStack::RackCompatible, Rack::Cache::Context,
92
+ :metastore => "file:#{CACHE_DIR}/rack/meta",
93
+ :entitystore => "file:#{CACHE_DIR}/rack/body",
94
+ :verbose => true
95
+
96
+ b.adapter :test do |stub|
97
+ stub.get('/', &response)
98
+ stub.post('/', &response)
99
+ end
100
+ end
101
+ end
102
+
103
+ extend Forwardable
104
+ def_delegators :@conn, :get, :post
105
+
106
+ def test_cache_get
107
+ assert_equal 'request:1', get('/', :user_agent => 'test').body
108
+ response = get('/', :user_agent => 'test')
109
+ assert_equal 'request:1', response.body
110
+ assert_equal 'text/plain', response['content-type']
111
+
112
+ assert_equal 'request:2', post('/').body
113
+ end
114
+
115
+ def test_doesnt_cache_post
116
+ assert_equal 'request:1', get('/').body
117
+ assert_equal 'request:2', post('/').body
118
+ assert_equal 'request:3', post('/').body
119
+ end
120
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+ require 'forwardable'
3
+
4
+ class FactoryTest < Test::Unit::TestCase
5
+ extend Forwardable
6
+ def_delegator FaradayStack, :build
7
+
8
+ class CustomConnection < Faraday::Connection
9
+ end
10
+
11
+ def test_default_connection
12
+ assert_instance_of Faraday::Connection, FaradayStack.default_connection
13
+ end
14
+
15
+ def test_build_subclass
16
+ assert_instance_of CustomConnection, build(CustomConnection)
17
+ end
18
+
19
+ def test_build_url
20
+ conn = FaradayStack.build('http://example.com')
21
+ assert_equal 'example.com', conn.host
22
+ end
23
+
24
+ def test_build_url_in_options
25
+ conn = FaradayStack.build(:url => 'http://example.com')
26
+ assert_equal 'example.com', conn.host
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+ require 'forwardable'
3
+
4
+ class FollowRedirectsTest < Test::Unit::TestCase
5
+ def setup
6
+ @conn = Faraday.new do |b|
7
+ b.use FaradayStack::FollowRedirects
8
+ b.adapter :test do |stub|
9
+ stub.get('/') { [301, {'Location' => '/found'}, ''] }
10
+ stub.post('/create') { [302, {'Location' => '/'}, ''] }
11
+ stub.get('/found') { [200, {'Content-Type' => 'text/plain'}, 'fin'] }
12
+ stub.get('/loop') { [302, {'Location' => '/loop'}, ''] }
13
+ stub.get('/temp') { [307, {'Location' => '/found'}, ''] }
14
+ end
15
+ end
16
+ end
17
+
18
+ extend Forwardable
19
+ def_delegators :@conn, :get, :post
20
+
21
+ def test_redirected
22
+ assert_equal 'fin', get('/').body
23
+ end
24
+
25
+ def test_redirected_twice
26
+ assert_equal 'fin', post('/create').body
27
+ end
28
+
29
+ def test_redirected_by_temp
30
+ assert_equal 'fin', get('/temp').body
31
+ end
32
+
33
+ def test_redirect_limit
34
+ assert_raises FaradayStack::RedirectLimitReached do
35
+ get('/loop')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,93 @@
1
+ require 'test_helper'
2
+
3
+ class ResponseMiddlewareTest < Test::Unit::TestCase
4
+ def setup
5
+ @json_handler = FaradayStack::ResponseJSON
6
+ @conn = Faraday.new do |b|
7
+ b.use @json_handler
8
+ b.adapter :test do |stub|
9
+ stub.get('json') { [200, {'Content-Type' => 'application/json; charset=utf-8'}, "[1,2,3]"] }
10
+ stub.get('bad_mime') { [200, {'Content-Type' => 'text/javascript; charset=utf-8'}, "[1,2,3]"] }
11
+ stub.get('js') { [200, {'Content-Type' => 'text/javascript'}, "alert('hello')"] }
12
+ stub.get('blank') { [200, {'Content-Type' => 'application/json'}, ''] }
13
+ stub.get('nil') { [200, {'Content-Type' => 'application/json'}, nil] }
14
+ stub.get('bad_json') { [200, {'Content-Type' => 'application/json'}, '<body></body>']}
15
+ stub.get('non_json') { [200, {'Content-Type' => 'text/html'}, '<body></body>']}
16
+ end
17
+ end
18
+ end
19
+
20
+ def process_only(*types)
21
+ @conn.builder.swap @json_handler, @json_handler, :content_type => types
22
+ end
23
+
24
+ def with_mime_type_fix(*types)
25
+ @conn.builder.insert_after @json_handler, FaradayStack::ResponseJSON::MimeTypeFix, :content_type => types
26
+ end
27
+
28
+ def test_uses_json_to_parse_json_content
29
+ response = @conn.get('json')
30
+ assert response.success?
31
+ assert_equal [1,2,3], response.body
32
+ end
33
+
34
+ def test_uses_json_to_parse_json_content_conditional
35
+ process_only('application/json')
36
+ response = @conn.get('json')
37
+ assert response.success?
38
+ assert_equal [1,2,3], response.body
39
+ end
40
+
41
+ def test_uses_json_to_parse_json_content_conditional_with_regexp
42
+ process_only(%r{/(x-)?json$})
43
+ response = @conn.get('json')
44
+ assert response.success?
45
+ assert_equal [1,2,3], response.body
46
+ end
47
+
48
+ def test_uses_json_to_skip_blank_content
49
+ response = @conn.get('blank')
50
+ assert response.success?
51
+ assert_nil response.body
52
+ end
53
+
54
+ def test_uses_json_to_skip_nil_content
55
+ response = @conn.get('nil')
56
+ assert response.success?
57
+ assert_nil response.body
58
+ end
59
+
60
+ def test_uses_json_to_raise_Faraday_Error_Parsing_with_no_json_content
61
+ assert_raises Faraday::Error::ParsingError do
62
+ @conn.get('bad_json')
63
+ end
64
+ end
65
+
66
+ def test_non_json_response
67
+ assert_raises Faraday::Error::ParsingError do
68
+ @conn.get('non_json')
69
+ end
70
+ end
71
+
72
+ def test_non_json_response_conditional
73
+ process_only('application/json')
74
+ response = @conn.get('non_json')
75
+ assert_equal 'text/html', response.headers['Content-Type']
76
+ assert_equal '<body></body>', response.body
77
+ end
78
+
79
+ def test_mime_type_fix
80
+ process_only('application/json')
81
+ with_mime_type_fix
82
+ response = @conn.get('bad_mime')
83
+ assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
84
+ assert_equal [1,2,3], response.body
85
+ end
86
+
87
+ def test_mime_type_fix_conditional
88
+ process_only('application/json')
89
+ with_mime_type_fix
90
+ response = @conn.get('js')
91
+ assert_equal 'text/javascript', response.headers['Content-Type']
92
+ end
93
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require 'faraday_stack'
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jeffersongirao_faraday-stack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mislav Marohnić
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-15 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: &2157616900 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0.6'
22
+ - - <
23
+ - !ruby/object:Gem::Version
24
+ version: '0.8'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: *2157616900
28
+ description:
29
+ email: mislav.marohnic@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Rakefile
35
+ - lib/faraday-stack.rb
36
+ - lib/faraday_stack/addressable_patch.rb
37
+ - lib/faraday_stack/caching.rb
38
+ - lib/faraday_stack/follow_redirects.rb
39
+ - lib/faraday_stack/instrumentation.rb
40
+ - lib/faraday_stack/rack_compatible.rb
41
+ - lib/faraday_stack/response_html.rb
42
+ - lib/faraday_stack/response_json.rb
43
+ - lib/faraday_stack/response_middleware.rb
44
+ - lib/faraday_stack/response_xml.rb
45
+ - lib/faraday_stack.rb
46
+ - test/caching_test.rb
47
+ - test/factory_test.rb
48
+ - test/follow_redirects_test.rb
49
+ - test/response_middleware_test.rb
50
+ - test/test_helper.rb
51
+ - README.md
52
+ homepage: https://github.com/jeffersongirao/faraday-stack
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ segments:
65
+ - 0
66
+ hash: -1051454488374554944
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ segments:
74
+ - 0
75
+ hash: -1051454488374554944
76
+ requirements: []
77
+ rubyforge_project: jeffersongirao_faraday-stack
78
+ rubygems_version: 1.8.10
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: A Temp fork of faraday-stack
82
+ test_files: []