Skip to content

Commit

Permalink
Refactor support/example_server
Browse files Browse the repository at this point in the history
  • Loading branch information
ixti committed Nov 12, 2014
1 parent 816b78a commit bb0ef37
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 102 deletions.
14 changes: 8 additions & 6 deletions spec/http/client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'spec_helper'

RSpec.describe HTTP::Client do
let(:test_endpoint) { "http://#{ExampleServer::ADDR}" }

StubbedClient = Class.new(HTTP::Client) do
def perform(request, options)
stubs.fetch(request.uri.to_s) { super(request, options) }
Expand Down Expand Up @@ -148,28 +150,28 @@ def simple_response(body, status = 200)
it 'calls finish_response before actual performance' do
allow(TCPSocket).to receive(:open) { throw :halt }
expect(client).to receive(:finish_response)
catch(:halt) { client.head "http://127.0.0.1:#{ExampleService::PORT}/" }
catch(:halt) { client.head test_endpoint }
end

it 'calls finish_response once body was fully flushed' do
expect(client).to receive(:finish_response).twice.and_call_original
client.get("http://127.0.0.1:#{ExampleService::PORT}/").to_s
client.get(test_endpoint).to_s
end

it 'fails on unexpected eof' do
expect { client.get("http://127.0.0.1:#{ExampleService::PORT}/eof").to_s }
expect { client.get("#{test_endpoint}/eof").to_s }
.to raise_error(IOError)
end

context 'with HEAD request' do
it 'does not iterates through body' do
expect(client).to_not receive(:readpartial)
client.head("http://127.0.0.1:#{ExampleService::PORT}/")
client.head(test_endpoint)
end

it 'finishes response after headers were received' do
expect(client).to receive(:finish_response).twice.and_call_original
client.head("http://127.0.0.1:#{ExampleService::PORT}/")
client.head(test_endpoint)
end
end

Expand Down Expand Up @@ -199,7 +201,7 @@ def simple_response(body, status = 200)
end

it 'properly reads body' do
body = client.get("http://127.0.0.1:#{ExampleService::PORT}/").to_s
body = client.get(test_endpoint).to_s
expect(body).to eq '<!doctype html>'
end
end
Expand Down
16 changes: 8 additions & 8 deletions spec/http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require 'json'

RSpec.describe HTTP do
let(:test_endpoint) { "http://127.0.0.1:#{ExampleService::PORT}/" }
let(:test_endpoint) { "http://#{ExampleServer::ADDR}" }

context 'getting resources' do
it 'is easy' do
Expand All @@ -12,21 +12,21 @@

context 'with URI instance' do
it 'is easy' do
response = HTTP.get URI(test_endpoint)
response = HTTP.get URI test_endpoint
expect(response.to_s).to match(/<!doctype html>/)
end
end

context 'with query string parameters' do
it 'is easy' do
response = HTTP.get "#{test_endpoint}params", :params => {:foo => 'bar'}
response = HTTP.get "#{test_endpoint}/params", :params => {:foo => 'bar'}
expect(response.to_s).to match(/Params!/)
end
end

context 'with query string parameters in the URI and opts hash' do
it 'includes both' do
response = HTTP.get "#{test_endpoint}multiple-params?foo=bar", :params => {:baz => 'quux'}
response = HTTP.get "#{test_endpoint}/multiple-params?foo=bar", :params => {:baz => 'quux'}
expect(response.to_s).to match(/More Params!/)
end
end
Expand Down Expand Up @@ -73,26 +73,26 @@

context 'posting forms to resources' do
it 'is easy' do
response = HTTP.post "#{test_endpoint}form", :form => {:example => 'testing-form'}
response = HTTP.post "#{test_endpoint}/form", :form => {:example => 'testing-form'}
expect(response.to_s).to eq('passed :)')
end
end

context 'posting with an explicit body' do
it 'is easy' do
response = HTTP.post "#{test_endpoint}body", :body => 'testing-body'
response = HTTP.post "#{test_endpoint}/body", :body => 'testing-body'
expect(response.to_s).to eq('passed :)')
end
end

context 'with redirects' do
it 'is easy for 301' do
response = HTTP.with_follow(true).get("#{test_endpoint}redirect-301")
response = HTTP.with_follow(true).get("#{test_endpoint}/redirect-301")
expect(response.to_s).to match(/<!doctype html>/)
end

it 'is easy for 302' do
response = HTTP.with_follow(true).get("#{test_endpoint}redirect-302")
response = HTTP.with_follow(true).get("#{test_endpoint}/redirect-302")
expect(response.to_s).to match(/<!doctype html>/)
end

Expand Down
102 changes: 14 additions & 88 deletions spec/support/example_server.rb
Original file line number Diff line number Diff line change
@@ -1,103 +1,29 @@
require 'webrick'
require 'singleton'
require 'forwardable'

class ExampleService < WEBrick::HTTPServlet::AbstractServlet
PORT = 65432 # rubocop:disable NumericLiterals
require 'support/example_server/servlet'

def do_GET(request, response) # rubocop:disable MethodName
case request.path
when '/'
handle_root(request, response)
when '/params'
handle_params(request, response)
when '/multiple-params'
handle_multiple_params(request, response)
when '/proxy'
response.status = 200
response.body = 'Proxy!'
when '/not-found'
response.body = 'not found'
response.status = 404
when '/redirect-301'
response.status = 301
response['Location'] = "http://127.0.0.1:#{PORT}/"
when '/redirect-302'
response.status = 302
response['Location'] = "http://127.0.0.1:#{PORT}/"
when '/eof'
request.instance_variable_get('@socket').close
else
response.status = 404
end
end
class ExampleServer
extend Forwardable

def handle_root(request, response)
response.status = 200
case request['Accept']
when 'application/json'
response['Content-Type'] = 'application/json'
response.body = '{"json": true}'
else
response['Content-Type'] = 'text/html'
response.body = '<!doctype html>'
end
end
include Singleton

def handle_params(request, response)
return unless request.query_string == 'foo=bar'
PORT = 65_432
ADDR = "127.0.0.1:#{PORT}"

response.status = 200
response.body = 'Params!'
def initialize
@server = WEBrick::HTTPServer.new :Port => PORT, :AccessLog => []
@server.mount '/', Servlet
end

def handle_multiple_params(request, response)
params = CGI.parse(request.query_string)

return unless params == {'foo' => ['bar'], 'baz' => ['quux']}

response.status = 200
response.body = 'More Params!'
end

def do_POST(request, response) # rubocop:disable MethodName
case request.path
when '/form'
if request.query['example'] == 'testing-form'
response.status = 200
response.body = 'passed :)'
else
response.status = 400
response.body = 'invalid! >:E'
end
when '/body'
if request.body == 'testing-body'
response.status = 200
response.body = 'passed :)'
else
response.status = 400
response.body = 'invalid! >:E'
end
else
response.status = 404
end
end

def do_HEAD(request, response) # rubocop:disable MethodName
case request.path
when '/'
response.status = 200
response['Content-Type'] = 'text/html'
else
response.status = 404
end
end
delegate [:start, :shutdown] => :@server
end

ExampleServer = WEBrick::HTTPServer.new(:Port => ExampleService::PORT, :AccessLog => [])
ExampleServer.mount '/', ExampleService
t = Thread.new { ExampleServer.instance.start }

t = Thread.new { ExampleServer.start }
trap('INT') do
ExampleServer.shutdown
ExampleServer.instance.shutdown
exit
end

Expand Down
106 changes: 106 additions & 0 deletions spec/support/example_server/servlet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
require 'webrick'

class ExampleServer
class Servlet < WEBrick::HTTPServlet::AbstractServlet
def not_found(_req, res)
res.status = 404
res.body = 'Not Found'
end

%w(get post head).each do |method|
class_eval <<-RUBY, __FILE__, __LINE__
def self.handlers
@handlers ||= {}
end
def self.#{method}(path, &block)
handlers["#{method}:\#{path}"] = block
end
def do_#{method.upcase}(req, res)
handler = self.class.handlers["#{method}:\#{req.path}"]
return instance_exec(req, res, &handler) if handler
not_found
end
RUBY
end

get '/' do |req, res|
res.status = 200

case req['Accept']
when 'application/json'
res['Content-Type'] = 'application/json'
res.body = '{"json": true}'
else
res['Content-Type'] = 'text/html'
res.body = '<!doctype html>'
end
end

get '/params' do |req, res|
next not_found unless 'foo=bar' == req.query_string

res.status = 200
res.body = 'Params!'
end

get '/multiple-params' do |req, res|
params = CGI.parse req.query_string

next not_found unless {'foo' => ['bar'], 'baz' => ['quux']} == params

res.status = 200
res.body = 'More Params!'
end

get '/proxy' do |_req, res|
res.status = 200
res.body = 'Proxy!'
end

get '/not-found' do |_req, res|
res.status = 404
res.body = 'not found'
end

get '/redirect-301' do |_req, res|
res.status = 301
res['Location'] = "http://#{ExampleServer::ADDR}/"
end

get '/redirect-302' do |_req, res|
res.status = 302
res['Location'] = "http://#{ExampleServer::ADDR}/"
end

get '/eof' do |req, _res|
req.instance_variable_get('@socket').close
end

post '/form' do |req, res|
if 'testing-form' == req.query['example']
res.status = 200
res.body = 'passed :)'
else
res.status = 400
res.body = 'invalid! >:E'
end
end

post '/body' do |req, res|
if 'testing-body' == req.body
res.status = 200
res.body = 'passed :)'
else
res.status = 400
res.body = 'invalid! >:E'
end
end

head '/' do |_req, res|
res.status = 200
res['Content-Type'] = 'text/html'
end
end
end

0 comments on commit bb0ef37

Please sign in to comment.