diff options
author | Jacob Vosmaer <jacob@gitlab.com> | 2017-01-02 18:59:07 +0100 |
---|---|---|
committer | Jacob Vosmaer <jacob@gitlab.com> | 2017-01-02 18:59:07 +0100 |
commit | d03e022b8816fd4193ff7a0a34e35573e8114e7f (patch) | |
tree | 1896a5c90f0eb99ecaa5fc09304cee7174657943 /lib/vendor/excon/tests/middlewares | |
parent | 3fe9cea03a6384fd8f57f10e172c134ed5c0552d (diff) | |
download | gitlab-shell-http-excon.tar.gz |
WIP Use excon for HTTP requestshttp-excon
Diffstat (limited to 'lib/vendor/excon/tests/middlewares')
8 files changed, 1091 insertions, 0 deletions
diff --git a/lib/vendor/excon/tests/middlewares/canned_response_tests.rb b/lib/vendor/excon/tests/middlewares/canned_response_tests.rb new file mode 100644 index 0000000..e4a70c1 --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/canned_response_tests.rb @@ -0,0 +1,34 @@ +Shindo.tests("Excon support for middlewares that return canned responses") do + the_body = "canned" + + canned_response_middleware = Class.new(Excon::Middleware::Base) do + define_method :request_call do |params| + params[:response] = { + :body => the_body, + :headers => {}, + :status => 200 + } + super(params) + end + end + + tests('does not mutate the canned response body').returns(the_body) do + Excon.get( + 'http://some-host.com/some-path', + :middlewares => [canned_response_middleware] + Excon.defaults[:middlewares] + ).body + end + + tests('yields non-mutated body to response_block').returns(the_body) do + body = '' + response_block = lambda { |chunk, _, _| body << chunk } + Excon.get( + 'http://some-host.com/some-path', + :middlewares => [canned_response_middleware] + Excon.defaults[:middlewares], + :response_block => response_block + ) + body + end + +end + diff --git a/lib/vendor/excon/tests/middlewares/capture_cookies_tests.rb b/lib/vendor/excon/tests/middlewares/capture_cookies_tests.rb new file mode 100644 index 0000000..0e681ce --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/capture_cookies_tests.rb @@ -0,0 +1,34 @@ +Shindo.tests("Excon redirecting with cookie preserved") do + env_init + + with_rackup('redirecting_with_cookie.ru') do + tests('second request will send cookies set by the first').returns('ok') do + Excon.get( + 'http://127.0.0.1:9292', + :path => '/sets_cookie', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::CaptureCookies, Excon::Middleware::RedirectFollower] + ).body + end + + tests('second request will send multiple cookies set by the first').returns('ok') do + Excon.get( + 'http://127.0.0.1:9292', + :path => '/sets_multi_cookie', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::CaptureCookies, Excon::Middleware::RedirectFollower] + ).body + end + end + + with_rackup('redirecting.ru') do + tests("runs normally when there are no cookies set").returns('ok') do + Excon.post( + 'http://127.0.0.1:9292', + :path => '/first', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::CaptureCookies, Excon::Middleware::RedirectFollower], + :body => "a=Some_content" + ).body + end + end + + env_restore +end diff --git a/lib/vendor/excon/tests/middlewares/decompress_tests.rb b/lib/vendor/excon/tests/middlewares/decompress_tests.rb new file mode 100644 index 0000000..aebba34 --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/decompress_tests.rb @@ -0,0 +1,157 @@ +Shindo.tests('Excon Decompress Middleware') do + env_init + + with_server('good') do + + before do + @connection ||= Excon.new( + 'http://127.0.0.1:9292/echo/content-encoded', + :method => :post, + :body => 'hello world', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::Decompress] + ) + end + + tests('gzip') do + resp = nil + + tests('response body decompressed').returns('hello world') do + resp = @connection.request( + :headers => { 'Accept-Encoding' => 'gzip, deflate;q=0' } + ) + resp[:body] + end + + tests('server sent content-encoding').returns('gzip') do + resp[:headers]['Content-Encoding-Sent'] + end + + tests('removes processed encoding from header').returns('') do + resp[:headers]['Content-Encoding'] + end + + tests('empty response body').returns('') do + resp = @connection.request(:body => '') + resp[:body] + end + end + + tests('deflate') do + resp = nil + + tests('response body decompressed').returns('hello world') do + resp = @connection.request( + :headers => { 'Accept-Encoding' => 'gzip;q=0, deflate' } + ) + resp[:body] + end + + tests('server sent content-encoding').returns('deflate') do + resp[:headers]['Content-Encoding-Sent'] + end + + tests('removes processed encoding from header').returns('') do + resp[:headers]['Content-Encoding'] + end + end + + tests('with pre-encoding') do + resp = nil + + tests('server sent content-encoding').returns('other, gzip') do + resp = @connection.request( + :headers => { 'Accept-Encoding' => 'gzip, deflate;q=0', + 'Content-Encoding-Pre' => 'other' } + ) + resp[:headers]['Content-Encoding-Sent'] + end + + tests('processed encoding removed from header').returns('other') do + resp[:headers]['Content-Encoding'] + end + + tests('response body decompressed').returns('hello world') do + resp[:body] + end + + end + + tests('with post-encoding') do + resp = nil + + tests('server sent content-encoding').returns('gzip, other') do + resp = @connection.request( + :headers => { 'Accept-Encoding' => 'gzip, deflate;q=0', + 'Content-Encoding-Post' => 'other' } + ) + resp[:headers]['Content-Encoding-Sent'] + end + + tests('unprocessed since last applied is unknown').returns('gzip, other') do + resp[:headers]['Content-Encoding'] + end + + tests('response body still compressed').returns('hello world') do + Zlib::GzipReader.new(StringIO.new(resp[:body])).read + end + + end + + tests('with a :response_block') do + captures = nil + resp = nil + + tests('server sent content-encoding').returns('gzip') do + captures = capture_response_block do |block| + resp = @connection.request( + :headers => { 'Accept-Encoding' => 'gzip'}, + :response_block => block + ) + end + resp[:headers]['Content-Encoding-Sent'] + end + + tests('unprocessed since :response_block was used').returns('gzip') do + resp[:headers]['Content-Encoding'] + end + + tests(':response_block passed unprocessed data').returns('hello world') do + body = captures.map {|capture| capture[0] }.join + Zlib::GzipReader.new(StringIO.new(body)).read + end + + end + + tests('adds Accept-Encoding if needed') do + + tests('without a :response_block').returns('deflate, gzip') do + resp = Excon.post( + 'http://127.0.0.1:9292/echo/request', + :body => 'hello world', + :middlewares => Excon.defaults[:middlewares] + + [Excon::Middleware::Decompress] + ) + request = Marshal.load(resp.body) + request[:headers]['Accept-Encoding'] + end + + tests('with a :response_block').returns(nil) do + captures = capture_response_block do |block| + Excon.post( + 'http://127.0.0.1:9292/echo/request', + :body => 'hello world', + :response_block => block, + :middlewares => Excon.defaults[:middlewares] + + [Excon::Middleware::Decompress] + ) + end + request = Marshal.load(captures.map {|capture| capture[0] }.join) + request[:headers]['Accept-Encoding'] + end + + end + + end + + env_restore +end diff --git a/lib/vendor/excon/tests/middlewares/escape_path_tests.rb b/lib/vendor/excon/tests/middlewares/escape_path_tests.rb new file mode 100644 index 0000000..f354a0f --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/escape_path_tests.rb @@ -0,0 +1,36 @@ +Shindo.tests('Excon Decompress Middleware') do + env_init + with_rackup('basic.ru') do + tests('encoded uri passed to connection') do + tests('GET /echo%20dirty').returns(200) do + connection = Excon::Connection.new({ + :host => '127.0.0.1', + :hostname => '127.0.0.1', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::EscapePath], + :nonblock => false, + :port => 9292, + :scheme => 'http', + :ssl_verify_peer => false + }) + response = connection.request(:method => :get, :path => '/echo%20dirty') + response[:status] + end + end + + tests('unencoded uri passed to connection') do + tests('GET /echo dirty').returns(200) do + connection = Excon::Connection.new({ + :host => '127.0.0.1', + :hostname => '127.0.0.1', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::EscapePath], + :nonblock => false, + :port => 9292, + :scheme => 'http', + :ssl_verify_peer => false + }) + response = connection.request(:method => :get, :path => '/echo dirty') + response[:status] + end + end + end +end diff --git a/lib/vendor/excon/tests/middlewares/idempotent_tests.rb b/lib/vendor/excon/tests/middlewares/idempotent_tests.rb new file mode 100644 index 0000000..4c58bce --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/idempotent_tests.rb @@ -0,0 +1,131 @@ +Shindo.tests('Excon request idempotencey') do + + before do + @connection = Excon.new('http://127.0.0.1:9292', :mock => true) + end + + after do + # flush any existing stubs after each test + Excon.stubs.clear + end + + tests("Non-idempotent call with an erroring socket").raises(Excon::Errors::SocketError) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 3 # First 3 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + @connection.request(:method => :get, :path => '/some-path') + end + + tests("Idempotent request with socket erroring first 3 times").returns(200) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 3 # First 3 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path') + response.status + end + + tests("Idempotent request with socket erroring first 5 times").raises(Excon::Errors::SocketError) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 5 # First 5 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path') + response.status + end + + tests("Lowered retry limit with socket erroring first time").returns(200) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 1 # First call fails. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path', :retry_limit => 2) + response.status + end + + tests("Lowered retry limit with socket erroring first 3 times").raises(Excon::Errors::SocketError) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 3 # First 3 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path', :retry_limit => 2) + response.status + end + + tests("Raised retry limit with socket erroring first 5 times").returns(200) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 5 # First 5 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path', :retry_limit => 8) + response.status + end + + tests("Raised retry limit with socket erroring first 9 times").raises(Excon::Errors::SocketError) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 9 # First 9 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path', :retry_limit => 8) + response.status + end + + tests("Retry limit in constructor with socket erroring first 5 times").returns(200) do + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 5 # First 5 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + + response = @connection.request(:method => :get, :idempotent => true, :path => '/some-path', :retry_limit => 6) + response.status + end + +end diff --git a/lib/vendor/excon/tests/middlewares/instrumentation_tests.rb b/lib/vendor/excon/tests/middlewares/instrumentation_tests.rb new file mode 100644 index 0000000..cc2f57d --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/instrumentation_tests.rb @@ -0,0 +1,315 @@ +require 'active_support/notifications' +require 'securerandom' + +class SimpleInstrumentor + class << self + attr_accessor :events, :blocks + + def instrument(name, params = {}, &block) + @events << name + @blocks << name if block_given? + + yield if block_given? + end + + def reset! + @events = [] + @blocks = [] + end + end +end + +Shindo.tests('Excon instrumentation') do + + after do + ActiveSupport::Notifications.unsubscribe("excon") + ActiveSupport::Notifications.unsubscribe("excon.request") + ActiveSupport::Notifications.unsubscribe("excon.response") + ActiveSupport::Notifications.unsubscribe("excon.retry") + ActiveSupport::Notifications.unsubscribe("excon.error") + ActiveSupport::Notifications.unsubscribe("gug") + Delorean.back_to_the_present + Excon.stubs.clear + end + + before do + SimpleInstrumentor.reset! + end + + def subscribe(match) + @events = [] + ActiveSupport::Notifications.subscribe(match) do |*args| + @events << ActiveSupport::Notifications::Event.new(*args) + end + end + + def make_request(idempotent = false, params = {}) + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => ActiveSupport::Notifications, + :mock => true + ) + if idempotent + params[:idempotent] = :true + end + connection.get(params) + end + + REQUEST_DELAY_SECONDS = 30 + def stub_success + Excon.stub({:method => :get}) { |params| + Delorean.jump REQUEST_DELAY_SECONDS + {:body => params[:body], :headers => params[:headers], :status => 200} + } + end + + def stub_retries + run_count = 0 + Excon.stub({:method => :get}) { |params| + run_count += 1 + if run_count <= 3 # First 3 calls fail. + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + else + {:body => params[:body], :headers => params[:headers], :status => 200} + end + } + end + + def stub_failure + Excon.stub({:method => :get}) { |params| + raise Excon::Errors::SocketError.new(Exception.new "Mock Error") + } + end + + tests('basic notification').returns(['excon.request', 'excon.response']) do + subscribe(/excon/) + stub_success + make_request + @events.map(&:name) + end + + tests('captures scheme, host, port, and path').returns([:host, :path, :port, :scheme]) do + subscribe(/excon/) + stub_success + make_request + [:host, :path, :port, :scheme].select {|k| @events.first.payload.has_key? k} + end + + tests('params in request overwrite those in constructor').returns('/cheezburger') do + subscribe(/excon/) + stub_success + make_request(false, :path => '/cheezburger') + @events.first.payload[:path] + end + + tests('notify on retry').returns(3) do + subscribe(/excon/) + stub_retries + make_request(true) + @events.count{|e| e.name =~ /retry/} + end + + tests('notify on error').returns(true) do + subscribe(/excon/) + stub_failure + raises(Excon::Errors::SocketError) do + make_request + end + + @events.any?{|e| e.name =~ /error/} + end + + tests('filtering').returns(['excon.request', 'excon.error']) do + subscribe(/excon.request/) + subscribe(/excon.error/) + stub_failure + raises(Excon::Errors::SocketError) do + make_request(true) + end + + @events.map(&:name) + end + + tests('more filtering').returns(['excon.retry', 'excon.retry', 'excon.retry']) do + subscribe(/excon.retry/) + stub_failure + raises(Excon::Errors::SocketError) do + make_request(true) + end + + @events.map(&:name) + end + + tests('indicates duration').returns(true) do + subscribe(/excon/) + stub_success + make_request + (@events.first.duration/1000 - REQUEST_DELAY_SECONDS).abs < 1 + end + + tests('standard instrumentor') do + + tests('success').returns( + ['excon.request', 'excon.retry', 'excon.retry', 'excon.retry', 'excon.error']) do + + begin + original_stderr = $stderr + $stderr = captured_stderr = StringIO.new + stub_failure + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => Excon::StandardInstrumentor, + :mock => true + ) + raises(Excon::Errors::SocketError) do + connection.get(:idempotent => true) + end + + captured_stderr.string.split("\n").reject {|line| line =~ %r{^ }}.map {|event| event.split(' ').first} + ensure + $stderr = original_stderr + end + end + + tests('authorization header REDACT') do + + @auth_header = 'Basic dXNlcjpwYXNz' + + begin + original_stderr = $stderr + $stderr = @captured_stderr = StringIO.new + stub_failure + raises(Excon::Errors::SocketError) do + @connection = Excon.new( + 'http://user:pass@127.0.0.1:9292', + :headers => { + 'Authorization' => @auth_header + }, + :instrumentor => Excon::StandardInstrumentor, + :mock => true + ) + @connection.get(:idempotent => true) + end + ensure + $stderr = original_stderr + end + + test('does not appear in response') do + !@captured_stderr.string.include?(@auth_header) + end + + test('does not mutate Authorization value') do + @connection.data[:headers]['Authorization'] == @auth_header + end + + end + + tests('password REDACT') do + + begin + original_stderr = $stderr + $stderr = @captured_stderr = StringIO.new + stub_failure + raises(Excon::Errors::SocketError) do + @connection = Excon.new( + 'http://user:pass@127.0.0.1:9292', + :instrumentor => Excon::StandardInstrumentor, + :mock => true + ) + @connection.get(:idempotent => true) + end + ensure + $stderr = original_stderr + end + + @password_param = '"pass"' + + test('does not appear in response') do + !@captured_stderr.string.include?(@password_param) + end + + test('does not mutate password value') do + @connection.data[:password] == "pass" + end + + end + + end + + tests('use our own instrumentor').returns( + ['excon.request', 'excon.retry', 'excon.retry', 'excon.retry', 'excon.error']) do + stub_failure + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => SimpleInstrumentor, + :mock => true + ) + raises(Excon::Errors::SocketError) do + connection.get(:idempotent => true) + end + + SimpleInstrumentor.events + end + + tests('always passes the block').returns( + ['excon.request', 'excon.response']) do + stub_success + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => SimpleInstrumentor, + :mock => true + ) + connection.get(:idempotent => true) + + SimpleInstrumentor.blocks + end + + tests('does not generate events when not provided').returns(0) do + subscribe(/excon/) + stub_success + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + connection.get(:idempotent => true) + @events.count + end + + tests('allows setting the prefix').returns( + ['gug.request', 'gug.retry', 'gug.retry','gug.retry', 'gug.error']) do + subscribe(/gug/) + stub_failure + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => ActiveSupport::Notifications, + :instrumentor_name => 'gug', + :mock => true + ) + raises(Excon::Errors::SocketError) do + connection.get(:idempotent => true) + end + @events.map(&:name) + end + + tests('allows setting the prefix when not idempotent', 'foo').returns( + ['gug.request', 'gug.error']) do + subscribe(/gug/) + stub_failure + connection = Excon.new( + 'http://127.0.0.1:9292', + :instrumentor => ActiveSupport::Notifications, + :instrumentor_name => 'gug', + :mock => true + ) + raises(Excon::Errors::SocketError) do + connection.get() + end + @events.map(&:name) + end + + with_rackup('basic.ru') do + tests('works unmocked').returns(['excon.request', 'excon.response']) do + subscribe(/excon/) + make_request(false, :mock => false) + @events.map(&:name) + end + end +end + diff --git a/lib/vendor/excon/tests/middlewares/mock_tests.rb b/lib/vendor/excon/tests/middlewares/mock_tests.rb new file mode 100644 index 0000000..49c25aa --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/mock_tests.rb @@ -0,0 +1,304 @@ +Shindo.tests('Excon stubs') do + env_init + + tests("missing stub").raises(Excon::Errors::StubNotFound) do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + connection.request(:method => :get, :path => '/content-length/100') + end + + tests("stub({})").raises(ArgumentError) do + Excon.stub({}) + end + + tests("stub({}, {}) {}").raises(ArgumentError) do + Excon.stub({}, {}) {} + end + + tests("stub({:method => :get}, {:body => 'body', :status => 200})") do + connection = nil + response = nil + + tests('response.body').returns('body') do + Excon.stub({:method => :get}, {:body => 'body', :status => 200}) + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + response = connection.request(:method => :get, :path => '/content-length/100') + + response.body + end + + tests('response.headers').returns({}) do + response.headers + end + + tests('response.status').returns(200) do + response.status + end + + tests('response_block yields body').returns('body') do + body = '' + response_block = lambda do |chunk, remaining_bytes, total_bytes| + body << chunk + end + connection.request(:method => :get, :path => '/content-length/100', :response_block => response_block) + body + end + + tests('response.body empty with response_block').returns('') do + response_block = lambda { |_, _, _| } + connection.request(:method => :get, :path => '/content-length/100', :response_block => response_block).body + end + + Excon.stubs.clear + + end + + tests("stub({:path => %r{/tests/(\S+)}}, {:body => $1, :status => 200})") do + connection = nil + response = nil + + tests('response.body').returns('test') do + Excon.stub({:path => %r{/tests/(\S+)}}) do |params| + { + :body => params[:captures][:path].first, + :status => 200 + } + end + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + response = connection.request(:method => :get, :path => '/tests/test') + + response.body + end + + tests('response.headers').returns({}) do + response.headers + end + + tests('response.status').returns(200) do + response.status + end + + Excon.stubs.clear + + end + + tests("stub({:body => 'body', :method => :get}) {|params| {:body => params[:body], :headers => params[:headers], :status => 200}}") do + connection = nil + response = nil + + tests('response.body').returns('body') do + Excon.stub({:body => 'body', :method => :get}) {|params| {:body => params[:body], :headers => params[:headers], :status => 200}} + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + response = connection.request(:body => 'body', :method => :get, :path => '/content-length/100') + + response.body + end + + tests('response.headers').returns({'Host' => '127.0.0.1:9292', 'User-Agent' => "excon/#{Excon::VERSION}"}) do + response.headers + end + + tests('response.status').returns(200) do + response.status + end + + tests('response_block yields body').returns('body') do + body = '' + response_block = lambda do |chunk, remaining_bytes, total_bytes| + body << chunk + end + connection.request(:body => 'body', :method => :get, :path => '/content-length/100', :response_block => response_block) + body + end + + tests('response.body empty with response_block').returns('') do + response_block = lambda { |_, _, _| } + connection.request(:body => 'body', :method => :get, :path => '/content-length/100', :response_block => response_block).body + end + + Excon.stubs.clear + + end + + tests("stub({:body => File.open(...), :method => :get}, { :status => 200 })") do + + tests('response.status').returns(200) do + file_path = File.join(File.dirname(__FILE__), '..', 'data', 'xs') + + Excon.stub( + { :body => File.read(file_path), :method => :get }, + { :status => 200 } + ) + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + response = connection.request(:body => File.open(file_path), :method => :get, :path => '/') + + response.status + end + + Excon.stubs.clear + + end + + tests("invalid stub response").raises(Excon::Errors::InvalidStub) do + Excon.stub({:body => 42, :method => :get}, {:status => 200}) + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + connection.request(:body => 42, :method => :get, :path => '/').status + end + + tests("mismatched stub").raises(Excon::Errors::StubNotFound) do + Excon.stub({:method => :post}, {:body => 'body'}) + Excon.get('http://127.0.0.1:9292/', :mock => true) + end + + with_server('good') do + tests('allow mismatched stub').returns(200) do + Excon.stub({:path => '/echo/request_count'}, {:body => 'body'}) + Excon.get( + 'http://127.0.0.1:9292/echo/request', + :mock => true, + :allow_unstubbed_requests => true + ).status + end + end + + Excon.stubs.clear + + tests("stub({}, {:body => 'x' * (Excon::DEFAULT_CHUNK_SIZE + 1)})") do + + test("response_block yields body") do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:body => 'x' * (Excon::DEFAULT_CHUNK_SIZE + 1)}) + + chunks = [] + response_block = lambda do |chunk, remaining_bytes, total_bytes| + chunks << chunk + end + connection.request(:method => :get, :path => '/content-length/100', :response_block => response_block) + chunks == ['x' * Excon::DEFAULT_CHUNK_SIZE, 'x'] + end + + tests("response.body empty with response_block").returns('') do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:body => 'x' * (Excon::DEFAULT_CHUNK_SIZE + 1)}) + response_block = lambda { |_, _, _| } + connection.request(:method => :get, :path => '/content-length/100', :response_block => response_block).body + end + + end + + Excon.stubs.clear + + tests("stub({:url => 'https://user:pass@foo.bar.com:9999/baz?quux=true'}, {:status => 200})") do + test("get(:expects => 200)") do + Excon.stub({:url => 'https://user:pass@foo.bar.com:9999/baz?quux=true'}, {:status => 200}) + Excon.new("https://user:pass@foo.bar.com:9999/baz?quux=true", :mock => true).get(:expects => 200) + true + end + end + + Excon.stubs.clear + + tests("stub({}, {:status => 404, :body => 'Not Found'}") do + connection = nil + + tests("request(:expects => 200, :method => :get, :path => '/')").raises(Excon::Errors::NotFound) do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:status => 404, :body => 'Not Found'}) + + connection.request(:expects => 200, :method => :get, :path => '/') + end + + tests("Expects exception should contain response object").returns(Excon::Response) do + begin + connection.request(:expects => 200, :method => :get, :path => '/') + rescue Excon::Errors::NotFound => e + e.response.class + end + end + + test("request(:expects => 200, :method => :get, :path => '/') with block does not invoke the block since it raises an error") do + block_called = false + begin + response_block = lambda do |_,_,_| + block_called = true + end + connection.request(:expects => 200, :method => :get, :path => '/', :response_block => response_block) + rescue Excon::Errors::NotFound + end + !block_called + end + + Excon.stubs.clear + + end + + tests("stub_for({})") do + tests("stub_for({})").returns([{}, {}]) do + Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {}) + + Excon.stub_for({}) + end + + Excon.stubs.clear + end + + tests("unstub({})") do + connection = nil + + tests("unstub({})").returns([{}, {}]) do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {}) + + Excon.unstub({}) + end + + tests("request(:method => :get)").raises(Excon::Errors::StubNotFound) do + connection.request(:method => :get) + end + + Excon.stubs.clear + end + + tests("global stubs") do + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:body => '1'}) + t = Thread.new do + Excon.stub({}, {:body => '2'}) + connection.request(:method => :get).body + end + tests("get on a different thread").returns('2') do + t.join.value + end + tests("get on main thread").returns('2') do + connection.request(:method => :get).body + end + Excon.stubs.clear + end + + tests("thread-local stubs") do + original_stubs_value = Excon.defaults[:stubs] + Excon.defaults[:stubs] = :local + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:body => '1'}) + t = Thread.new do + Excon.stub({}, {:body => '2'}) + connection.request(:method => :get).body + end + tests("get on a different thread").returns('2') do + t.join.value + end + tests("get on main thread").returns('1') do + connection.request(:method => :get).body + end + Excon.stubs.clear + + Excon.defaults[:stubs] = original_stubs_value + end + + env_restore +end diff --git a/lib/vendor/excon/tests/middlewares/redirect_follower_tests.rb b/lib/vendor/excon/tests/middlewares/redirect_follower_tests.rb new file mode 100644 index 0000000..d99271b --- /dev/null +++ b/lib/vendor/excon/tests/middlewares/redirect_follower_tests.rb @@ -0,0 +1,80 @@ +Shindo.tests('Excon redirector support') do + env_init + + tests("request(:method => :get, :path => '/old').body").returns('new') do + Excon.stub( + { :path => '/old' }, + { + :headers => { 'Location' => 'http://127.0.0.1:9292/new' }, + :body => 'old', + :status => 301 + } + ) + + Excon.stub( + { :path => '/new' }, + { + :body => 'new', + :status => 200 + } + ) + + Excon.get( + 'http://127.0.0.1:9292', + :path => '/old', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower], + :mock => true + ).body + end + + env_restore +end + +Shindo.tests('Excon redirect support for relative Location headers') do + env_init + + tests("request(:method => :get, :path => '/old').body").returns('new') do + Excon.stub( + { :path => '/old' }, + { + :headers => { 'Location' => '/new' }, + :body => 'old', + :status => 301 + } + ) + + Excon.stub( + { :path => '/new' }, + { + :body => 'new', + :status => 200 + } + ) + + Excon.get( + 'http://127.0.0.1:9292', + :path => '/old', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower], + :mock => true + ).body + end + + env_restore +end + +Shindo.tests("Excon redirecting post request") do + env_init + + with_rackup('redirecting.ru') do + tests("request not have content-length and body").returns('ok') do + Excon.post( + 'http://127.0.0.1:9292', + :path => '/first', + :middlewares => Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower], + :body => "a=Some_content" + ).body + end + end + + env_restore +end |