1
0
Fork 0
mirror of https://github.com/jnunemaker/httparty synced 2023-03-27 23:23:07 -04:00

Cucumber features and steps for most functionality as of the 0.2.8

version.  No features for the CLI yet.

Signed-off-by: John Nunemaker <nunemaker@gmail.com>
This commit is contained in:
Don Petersen 2009-01-29 12:37:10 +08:00 committed by John Nunemaker
parent 5704725703
commit 2febfe3c83
13 changed files with 285 additions and 1 deletions

View file

@ -1,4 +1,5 @@
bin/httparty
cucumber.yml
examples/aaws.rb
examples/basic.rb
examples/delicious.rb
@ -6,6 +7,16 @@ examples/google.rb
examples/rubyurl.rb
examples/twitter.rb
examples/whoismyrep.rb
features/basic_authentication.feature
features/command_line.feature
features/deals_with_http_error_codes.feature
features/handles_multiple_formats.feature
features/steps/env.rb
features/steps/httparty_response_steps.rb
features/steps/httparty_steps.rb
features/steps/mongrel_helper.rb
features/steps/remote_service_steps.rb
features/supports_redirection.feature
History
httparty.gemspec
lib/core_extensions.rb

View file

@ -6,6 +6,7 @@ require 'rake'
require 'echoe'
require 'spec/rake/spectask'
require "lib/#{ProjectName}/version"
require 'cucumber/rake/task'
Echoe.new(ProjectName, HTTParty::Version) do |p|
p.description = "Makes http fun! Also, makes consuming restful web services dead easy."
@ -41,3 +42,7 @@ task :default => :spec
Spec::Rake::SpecTask.new do |t|
t.spec_files = FileList["spec/**/*_spec.rb"]
end
Cucumber::Rake::Task.new(:features) do |t|
t.cucumber_opts = "--format pretty"
end

1
cucumber.yml Normal file
View file

@ -0,0 +1 @@
default: features

View file

@ -0,0 +1,20 @@
Feature: Basic Authentication
As a developer
I want to be able to use a service that requires Basic Authentication
Because that is not an uncommon requirement
Scenario: Passing no credentials to a page requiring Basic Authentication
Given a restricted page at '/protected.html'
When I call HTTParty#get with '/protected.html'
Then it should return a response with a 401 response code
Scenario: Passing proper credentials to a page requiring Basic Authentication
Given a remote service that returns 'Authenticated Page'
And that service is accessed at the path '/protected.html'
And that service is protected by Basic Authentication
And that service requires the username 'jcash' with the password 'maninblack'
When I call HTTParty#get with '/protected.html' and a basic_auth hash:
| username | password |
| jcash | maninblack |
Then the return value should match 'Authenticated Page'

View file

@ -0,0 +1,7 @@
Feature: Command Line
As a developer
I want to be able to harness the power of HTTParty from the command line
Because that would make quick testing and debugging easy
And 'easy' is my middle name
And I'm kidding it's actually 'Danger'!

View file

@ -0,0 +1,26 @@
Feature: Deals with HTTP error codes
As a developer
I want to be informed of non-successful responses
Because sometimes thing explode
And I should probably know what happened
Scenario: A response of '404 - Not Found'
Given a remote service that returns a 404 status code
And that service is accessed at the path '/service.html'
When I call HTTParty#get with '/service.html'
Then it should return a response with a 404 response code
Scenario: A response of '500 - Internal Server Error'
Given a remote service that returns a 500 status code
And that service is accessed at the path '/service.html'
When I call HTTParty#get with '/service.html'
Then it should return a response with a 500 response code
Scenario: A non-successful response where I need the body
Given a remote service that returns a 400 status code
And the response from the service has a body of 'Bad response'
And that service is accessed at the path '/service.html'
When I call HTTParty#get with '/service.html'
Then it should return a response with a 400 response code
And the return value should match 'Bad response'

View file

@ -0,0 +1,34 @@
Feature: Handles Multiple Formats
As a developer
I want to be able to consume remote services of many different formats
And I want those formats to be automatically detected and handled
Because web services take many forms
And I don't want to have to do any extra work
Scenario: An HTML service
Given a remote service that returns '<h1>Some HTML</h1>'
And that service is accessed at the path '/service.html'
And the response from the service has a Content-Type of 'text/html'
When I call HTTParty#get with '/service.html'
Then it should return a String
And the return value should match '<h1>Some HTML</h1>'
Scenario: A JSON service
Given a remote service that returns '{ "jennings": "waylon", "cash": "johnny" }'
And that service is accessed at the path '/service.json'
And the response from the service has a Content-Type of 'application/json'
When I call HTTParty#get with '/service.json'
Then it should return a Hash equaling:
| key | value |
| jennings | waylon |
| cash | johnny |
Scenario: An XML Service
Given a remote service that returns '<singer>waylon jennings</singer>'
And that service is accessed at the path '/service.xml'
And the response from the service has a Content-Type of 'text/xml'
When I call HTTParty#get with '/service.xml'
Then it should return a Hash equaling:
| key | value |
| singer | waylon jennings |

15
features/steps/env.rb Normal file
View file

@ -0,0 +1,15 @@
require 'mongrel'
require 'activesupport'
require 'lib/httparty'
require 'spec/expectations'
Before do
port = ENV["HTTPARTY_PORT"] || 31981
@host_and_port = "0.0.0.0:#{port}"
@server = Mongrel::HttpServer.new("0.0.0.0", port)
@server.run
end
After do
@server.stop
end

View file

@ -0,0 +1,26 @@
Then /it should return an? (\w+)$/ do |class_string|
@response_from_httparty.should be_an_instance_of(class_string.constantize)
end
Then /the return value should match '(.*)'/ do |expected_text|
@response_from_httparty.should eql(expected_text)
end
Then /it should return a Hash equaling:/ do |hash_table|
@response_from_httparty.should be_an_instance_of(Hash)
@response_from_httparty.keys.length.should eql(hash_table.rows.length)
hash_table.hashes.each do |pair|
key, value = pair["key"], pair["value"]
@response_from_httparty.keys.should include(key)
@response_from_httparty[key].should eql(value)
end
end
Then /it should return a response with a (\d+) response code/ do |code|
@response_from_httparty.code.should eql(code)
end
Then /it should raise an HTTParty::RedirectionTooDeep exception/ do
@exception_from_httparty.should_not be_nil
@exception_from_httparty.class.should eql(HTTParty::RedirectionTooDeep)
end

View file

@ -0,0 +1,15 @@
When /I call HTTParty#get with '(.*)'$/ do |url|
begin
@response_from_httparty = HTTParty.get("http://#{@host_and_port}#{url}")
rescue HTTParty::RedirectionTooDeep => e
@exception_from_httparty = e
end
end
When /I call HTTParty#get with '(.*)' and a basic_auth hash:/ do |url, auth_table|
h = auth_table.hashes.first
@response_from_httparty = HTTParty.get(
"http://#{@host_and_port}#{url}",
:basic_auth => { :username => h["username"], :password => h["password"] }
)
end

View file

@ -0,0 +1,55 @@
def basic_mongrel_handler
Class.new(Mongrel::HttpHandler) do
attr_writer :content_type, :response_body, :response_code
def initialize
@content_type = "text/html"
@response_body = ""
@response_code = 200
@custom_headers = {}
end
def process(request, response)
reply_with(response, @response_code, @response_body)
end
def reply_with(response, code, response_body)
response.start(code) do |head, body|
head["Content-Type"] = @content_type
@custom_headers.each { |k,v| head[k] = v }
body.write(response_body)
end
end
end
end
def new_mongrel_handler
basic_mongrel_handler.new
end
def add_basic_authentication_to(handler)
m = Module.new do
attr_writer :username, :password
def self.extended(base)
base.instance_eval { @custom_headers["WWW-Authenticate"] = 'Basic Realm="Super Secret Page"' }
base.class_eval { alias_method_chain :process, :basic_authentication }
end
def process_with_basic_authentication(request, response)
if authorized?(request) then process_without_basic_authentication(request, response)
else reply_with(response, 401, "Incorrect. You have 20 seconds to comply.")
end
end
def authorized?(request)
request.params["HTTP_AUTHORIZATION"] == "Basic " + Base64.encode64("#{@username}:#{@password}").strip
end
end
handler.extend(m)
end
def new_mongrel_redirector(target_url, relative_path = false)
target_url = "http://#{@host_and_port}#{target_url}" unless relative_path
Mongrel::RedirectHandler.new(target_url)
end

View file

@ -0,0 +1,47 @@
Given /a remote service that returns '(.*)'/ do |response_body|
@handler = new_mongrel_handler
Given "the response from the service has a body of '#{response_body}'"
end
Given /a remote service that returns a (\d+) status code/ do |code|
@handler = new_mongrel_handler
@handler.response_code = code
end
Given /that service is accessed at the path '(.*)'/ do |path|
@server.register(path, @handler)
end
Given /the response from the service has a Content-Type of '(.*)'/ do |content_type|
@handler.content_type = content_type
end
Given /the response from the service has a body of '(.*)'/ do |response_body|
@handler.response_body = response_body
end
Given /the url '(.*)' redirects to '(.*)'/ do |redirection_url, target_url|
@server.register redirection_url, new_mongrel_redirector(target_url)
end
Given /that service is protected by Basic Authentication/ do
add_basic_authentication_to @handler
end
Given /that service requires the username '(.*)' with the password '(.*)'/ do |username, password|
@handler.username = username
@handler.password = password
end
Given /a restricted page at '(.*)'/ do |url|
Given "a remote service that returns 'A response I will never see'"
And "that service is accessed at the path '#{url}'"
And "that service is protected by Basic Authentication"
And "that service requires the username 'something' with the password 'secret'"
end
# This joins the server thread, and halts cucumber, so you can actually hit the
# server with a browser. Runs until you kill it with Ctrl-c
Given /I want to hit this in a browser/ do
@server.acceptor.join
end

View file

@ -0,0 +1,22 @@
Feature: Supports Redirection
As a developer
I want to work with services that may redirect me
And I want it to follow a reasonable number of redirects
Because sometimes web services do that
Scenario: A service that redirects once
Given a remote service that returns 'Service Response'
And that service is accessed at the path '/service.html'
And the url '/redirector.html' redirects to '/service.html'
When I call HTTParty#get with '/redirector.html'
Then the return value should match 'Service Response'
# TODO: Look in to why this actually fails...
Scenario: A service that redirects to a relative URL
Scenario: A service that redirects infinitely
Given the url '/first.html' redirects to '/second.html'
And the url '/second.html' redirects to '/first.html'
When I call HTTParty#get with '/first.html'
Then it should raise an HTTParty::RedirectionTooDeep exception