curb-fu 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/curb-fu.rb +64 -0
- data/lib/curb-fu/authentication.rb +5 -0
- data/lib/curb-fu/core_ext.rb +59 -0
- data/lib/curb-fu/entity.rb +54 -0
- data/lib/curb-fu/request.rb +12 -0
- data/lib/curb-fu/request/base.rb +118 -0
- data/lib/curb-fu/request/common.rb +34 -0
- data/lib/curb-fu/request/parameter.rb +33 -0
- data/lib/curb-fu/request/test.rb +153 -0
- data/lib/curb-fu/response.rb +179 -0
- data/lib/curb-fu/test.rb +6 -0
- data/lib/curb-fu/test/request_logger.rb +31 -0
- data/lib/curb-fu/test/server.rb +21 -0
- data/spec/fixtures/foo.txt +1 -0
- data/spec/lib/curb-fu/core_ext_spec.rb +100 -0
- data/spec/lib/curb-fu/entity_spec.rb +37 -0
- data/spec/lib/curb-fu/request/base_spec.rb +240 -0
- data/spec/lib/curb-fu/request/parameter_spec.rb +77 -0
- data/spec/lib/curb-fu/request/test_spec.rb +223 -0
- data/spec/lib/curb-fu/response_spec.rb +99 -0
- data/spec/lib/curb_fu_spec.rb +49 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +11 -0
- metadata +95 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
module CurbFu
|
2
|
+
module Response
|
3
|
+
class Base
|
4
|
+
attr_accessor :status, :body, :headers
|
5
|
+
|
6
|
+
def initialize(status, headers, body)
|
7
|
+
@status = status
|
8
|
+
set_response_type(status)
|
9
|
+
@body = body
|
10
|
+
@headers = headers.is_a?(String) ? parse_headers(headers) : headers
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?
|
14
|
+
self.is_a?(CurbFu::Response::Success)
|
15
|
+
end
|
16
|
+
|
17
|
+
def redirect?
|
18
|
+
self.is_a?(CurbFu::Response::Redirection)
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure?
|
22
|
+
!(success? || redirect?)
|
23
|
+
end
|
24
|
+
|
25
|
+
def server_fail?
|
26
|
+
self.is_a?(CurbFu::Response::ServerError)
|
27
|
+
end
|
28
|
+
|
29
|
+
def client_fail?
|
30
|
+
self.is_a?(CurbFu::Response::ClientError)
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_headers(header_string)
|
34
|
+
header_lines = header_string.split($/)
|
35
|
+
header_lines.shift
|
36
|
+
header_lines.inject({}) do |hsh, line|
|
37
|
+
whole_enchillada, key, value = /^(.*?):\s*(.*)$/.match(line.chomp).to_a
|
38
|
+
hsh[key] = value unless whole_enchillada.nil?
|
39
|
+
hsh
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hash
|
44
|
+
{ :status => status, :body => body, :headers => headers }
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_response_type(status)
|
48
|
+
case status
|
49
|
+
when 100..199 then
|
50
|
+
self.extend CurbFu::Response::Information
|
51
|
+
case self.status
|
52
|
+
when 101 then self.extend CurbFu::Response::Continue
|
53
|
+
when 102 then self.extend CurbFu::Response::SwitchProtocl
|
54
|
+
end
|
55
|
+
when 200..299 then
|
56
|
+
self.extend CurbFu::Response::Success
|
57
|
+
case self.status
|
58
|
+
when 200 then self.extend CurbFu::Response::OK
|
59
|
+
when 201 then self.extend CurbFu::Response::Created
|
60
|
+
when 202 then self.extend CurbFu::Response::Accepted
|
61
|
+
when 203 then self.extend CurbFu::Response::NonAuthoritativeInformation
|
62
|
+
when 204 then self.extend CurbFu::Response::NoContent
|
63
|
+
when 205 then self.extend CurbFu::Response::ResetContent
|
64
|
+
when 206 then self.extend CurbFu::Response::PartialContent
|
65
|
+
end
|
66
|
+
when 300..399 then
|
67
|
+
self.extend CurbFu::Response::Redirection
|
68
|
+
case self.status
|
69
|
+
when 300 then self.extend CurbFu::Response::MultipleChoice
|
70
|
+
when 301 then self.extend CurbFu::Response::MovedPermanently
|
71
|
+
when 302 then self.extend CurbFu::Response::Found
|
72
|
+
when 303 then self.extend CurbFu::Response::SeeOther
|
73
|
+
when 304 then self.extend CurbFu::Response::NotModified
|
74
|
+
when 305 then self.extend CurbFu::Response::UseProxy
|
75
|
+
when 307 then self.extend CurbFu::Response::TemporaryRedirect
|
76
|
+
end
|
77
|
+
when 400..499 then
|
78
|
+
self.extend CurbFu::Response::ClientError
|
79
|
+
case self.status
|
80
|
+
when 400 then self.extend CurbFu::Response::BadRequest
|
81
|
+
when 401 then self.extend CurbFu::Response::Unauthorized
|
82
|
+
when 402 then self.extend CurbFu::Response::PaymentRequired
|
83
|
+
when 403 then self.extend CurbFu::Response::Forbidden
|
84
|
+
when 404 then self.extend CurbFu::Response::NotFound
|
85
|
+
when 405 then self.extend CurbFu::Response::MethodNotAllowed
|
86
|
+
when 406 then self.extend CurbFu::Response::NotAcceptable
|
87
|
+
when 407 then self.extend CurbFu::Response::ProxyAuthenticationRequired
|
88
|
+
when 408 then self.extend CurbFu::Response::RequestTimeOut
|
89
|
+
when 409 then self.extend CurbFu::Response::Conflict
|
90
|
+
when 410 then self.extend CurbFu::Response::Gone
|
91
|
+
when 411 then self.extend CurbFu::Response::LengthRequired
|
92
|
+
when 412 then self.extend CurbFu::Response::PreconditionFailed
|
93
|
+
when 413 then self.extend CurbFu::Response::RequestEntityTooLarge
|
94
|
+
when 414 then self.extend CurbFu::Response::RequestURITooLong
|
95
|
+
when 415 then self.extend CurbFu::Response::UnsupportedMediaType
|
96
|
+
when 416 then self.extend CurbFu::Response::UnsupportedMediaType
|
97
|
+
when 417 then self.extend CurbFu::Response::ExpectationFailed
|
98
|
+
end
|
99
|
+
when 500..599 then
|
100
|
+
self.extend CurbFu::Response::ServerError
|
101
|
+
case self.status
|
102
|
+
when 500 then self.extend CurbFu::Response::InternalServerError
|
103
|
+
when 501 then self.extend CurbFu::Response::NotImplemented
|
104
|
+
when 502 then self.extend CurbFu::Response::BadGateway
|
105
|
+
when 503 then self.extend CurbFu::Response::ServiceUnavailable
|
106
|
+
when 504 then self.extend CurbFu::Response::GatewayTimeOut
|
107
|
+
when 505 then self.extend CurbFu::Response::VersionNotSupported
|
108
|
+
end
|
109
|
+
else
|
110
|
+
self.extend CurbFu::Response::UnknownResponse
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class << self
|
115
|
+
def from_rack_response(rack)
|
116
|
+
raise ArgumentError.new("Rack response may not be nil") if rack.nil?
|
117
|
+
response = self.new(rack.status, rack.headers, rack.body)
|
118
|
+
end
|
119
|
+
|
120
|
+
def from_curb_response(curb)
|
121
|
+
response = self.new(curb.response_code, curb.header_str, curb.body_str)
|
122
|
+
response
|
123
|
+
end
|
124
|
+
|
125
|
+
def from_hash(hash)
|
126
|
+
return nil if hash.nil?
|
127
|
+
self.new(hash[:status], hash[:headers], hash[:body])
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
module Information; end
|
133
|
+
module Continue; def self.to_i; 100; end; end
|
134
|
+
module SwitchProtocl; end
|
135
|
+
module Success; def self.to_i; 200; end; end
|
136
|
+
module OK; def self.to_i; 200; end; end
|
137
|
+
module Created; def self.to_i; 201; end; end
|
138
|
+
module Accepted; def self.to_i; 202; end; end
|
139
|
+
module NonAuthoritativeInformation; end
|
140
|
+
module NoContent; end
|
141
|
+
module ResetContent; end
|
142
|
+
module PartialContent; end
|
143
|
+
module Redirection; end # 3xx
|
144
|
+
module MultipleChoice; end # 300
|
145
|
+
module MovedPermanently; end # 301
|
146
|
+
module Found; def self.to_i; 302; end; end
|
147
|
+
module SeeOther; end # 303
|
148
|
+
module NotModified; end # 304
|
149
|
+
module UseProxy; end # 305
|
150
|
+
module TemporaryRedirect; end # 307
|
151
|
+
module ClientError; end # 4xx
|
152
|
+
module BadRequest; end # 400
|
153
|
+
module Unauthorized; end # 401
|
154
|
+
module PaymentRequired; end # 402
|
155
|
+
module Forbidden; end # 403
|
156
|
+
module NotFound; def self.to_i; 404; end; end
|
157
|
+
module MethodNotAllowed; end # 405
|
158
|
+
module NotAcceptable; end # 406
|
159
|
+
module ProxyAuthenticationRequired; end # 407
|
160
|
+
module RequestTimeOut; end # 408
|
161
|
+
module Conflict; end # 409
|
162
|
+
module Gone; def self.to_i; 410; end; end
|
163
|
+
module LengthRequired; end # 411
|
164
|
+
module PreconditionFailed; end # 412
|
165
|
+
module RequestEntityTooLarge; end # 413
|
166
|
+
module RequestURITooLong; end # 414
|
167
|
+
module UnsupportedMediaType; end # 415
|
168
|
+
module RequestedRangeNotSatisfiable; end # 416
|
169
|
+
module ExpectationFailed; end # 417
|
170
|
+
module ServerError; end # 5xx
|
171
|
+
module InternalServerError; def self.to_i; 500; end; end
|
172
|
+
module NotImplemented; end # 501
|
173
|
+
module BadGateway; end # 502
|
174
|
+
module ServiceUnavailable; def self.to_i; 503; end; end
|
175
|
+
module GatewayTimeOut; end # 504
|
176
|
+
module VersionNotSupported; end # 505
|
177
|
+
module UnknownResponse; end
|
178
|
+
end
|
179
|
+
end
|
data/lib/curb-fu/test.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module CurbFu
|
2
|
+
module Test
|
3
|
+
class RequestLogger
|
4
|
+
class << self
|
5
|
+
def entries(host)
|
6
|
+
@entries ||= {}
|
7
|
+
@entries[host] ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def log(env)
|
11
|
+
req = Rack::Request.new(env)
|
12
|
+
url = env['PATH_INFO']
|
13
|
+
post_params = req.POST
|
14
|
+
host = env['HTTP_HOST'] || env['SERVER_NAME']
|
15
|
+
entries(host) << { :url => url, :params => post_params }
|
16
|
+
end
|
17
|
+
def requested?(host, url, params = nil)
|
18
|
+
url_found = (url.is_a?(String)) ?
|
19
|
+
!entries(host).find { |entry| entry[:url] == url }.nil? :
|
20
|
+
!entries(host).find { |entry| entry[:url] =~ url }.nil?
|
21
|
+
if params.nil?
|
22
|
+
return url_found
|
23
|
+
else
|
24
|
+
params_found = !entries(host).find { |entry| entry[:params] == params }.nil?
|
25
|
+
url_found && params_found
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module CurbFu
|
4
|
+
module Test
|
5
|
+
class Server
|
6
|
+
def self.serve(&blk)
|
7
|
+
Rack::Builder.app do
|
8
|
+
run lambda { |env|
|
9
|
+
CurbFu::Test::RequestLogger.log(env)
|
10
|
+
yield(env)
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.error!(message)
|
16
|
+
puts message
|
17
|
+
raise StandardError, message
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
asdf
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'curb-fu/core_ext'
|
3
|
+
|
4
|
+
describe "module inclusion" do
|
5
|
+
it "should include appropriate InstanceMethods" do
|
6
|
+
class Tester
|
7
|
+
include CurbFu::ObjectExtensions
|
8
|
+
end
|
9
|
+
|
10
|
+
Tester.new.should respond_to(:to_param)
|
11
|
+
end
|
12
|
+
it "should not overwrite a pre-existing method named :to_param" do
|
13
|
+
class TesterWithToParam
|
14
|
+
def to_param
|
15
|
+
"hooray, to_param!"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
TesterWithToParam.send(:include, CurbFu::ObjectExtensions)
|
20
|
+
TesterWithToParam.new.to_param.should == "hooray, to_param!"
|
21
|
+
end
|
22
|
+
it "should not overwrite the pre-existing method even if it comes from a module" do
|
23
|
+
module ActsLikeRails
|
24
|
+
def to_param
|
25
|
+
"foo"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
class TesterWithModule
|
29
|
+
include ActsLikeRails
|
30
|
+
end
|
31
|
+
TesterWithModule.send(:include, CurbFu::ObjectExtensions)
|
32
|
+
TesterWithModule.new.to_param.should == "foo"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe String do
|
37
|
+
it "should respond_to #to_param" do
|
38
|
+
"".should respond_to(:to_param)
|
39
|
+
end
|
40
|
+
describe "to_param" do
|
41
|
+
it "should return itself as the value for the passed-in name" do
|
42
|
+
"foo".to_param("quux").should == "quux=foo"
|
43
|
+
end
|
44
|
+
it "should be CGI escaped" do
|
45
|
+
"Whee, some 'unsafe' uri things".to_param("safe").should == "safe=Whee%2C+some+%27unsafe%27+uri+things"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe Hash do
|
51
|
+
it "should respond to #to_param" do
|
52
|
+
{}.should respond_to(:to_param)
|
53
|
+
end
|
54
|
+
describe "to_param" do
|
55
|
+
it "should collect its keys and values into parameter pairs, prepending the provided prefix" do
|
56
|
+
{
|
57
|
+
"kraplach" => "messy",
|
58
|
+
"zebot" => 2003
|
59
|
+
}.to_param("things").should == "things[kraplach]=messy&things[zebot]=2003"
|
60
|
+
end
|
61
|
+
it "should handle having an array as one of its parameters" do
|
62
|
+
result = {
|
63
|
+
"vielleicht" => "perhaps",
|
64
|
+
"ratings" => [5, 3, 5, 2, 4]
|
65
|
+
}.to_param("things")
|
66
|
+
result.split('&').size.should == 6
|
67
|
+
result.should =~ /things\[vielleicht\]=perhaps/
|
68
|
+
result.should =~ /things\[ratings\]\[\]=5/
|
69
|
+
result.should =~ /things\[ratings\]\[\]=3/
|
70
|
+
result.should =~ /things\[ratings\]\[\]=5/
|
71
|
+
result.should =~ /things\[ratings\]\[\]=2/
|
72
|
+
result.should =~ /things\[ratings\]\[\]=4/
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe Array do
|
78
|
+
it "should respond_to #to_param" do
|
79
|
+
[].should respond_to(:to_param)
|
80
|
+
end
|
81
|
+
describe "to_param" do
|
82
|
+
it "should join each element, prepending a provided key prefix" do
|
83
|
+
[1, 23, 5].to_param("magic_numbers").should == ["magic_numbers[]=1", "magic_numbers[]=23", "magic_numbers[]=5"].join("&")
|
84
|
+
end
|
85
|
+
it "should call to_param on each element, too" do
|
86
|
+
[1, 23, {"barkley" => 5}].to_param("magic_numbers").should == "magic_numbers[]=1&magic_numbers[]=23&magic_numbers[][barkley]=5"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe Integer do
|
92
|
+
it "should respond_to #to_param" do
|
93
|
+
1.should respond_to(:to_param)
|
94
|
+
end
|
95
|
+
describe "to_param" do
|
96
|
+
it "should return a stringified version of itself, using the provided key" do
|
97
|
+
5.to_param("fixnum").should == "fixnum=5"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe "CurbFu::Entity" do
|
4
|
+
before(:each) do
|
5
|
+
@entity = CurbFu::Entity.new
|
6
|
+
@entity.data = {
|
7
|
+
:zoltan => "Space Emperor!",
|
8
|
+
"em-dashes" => "more space=good"
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "to_request_data" do
|
13
|
+
it "should be able to convert parameters into json" do
|
14
|
+
@entity.content_type = :json
|
15
|
+
|
16
|
+
JSON.parse(@entity.to_request_data).should include("zoltan" => "Space Emperor!", "em-dashes" => "more space=good")
|
17
|
+
end
|
18
|
+
it "should be able to convert parameters into 'XML'" do
|
19
|
+
pending "We need to choose an xml library"
|
20
|
+
|
21
|
+
@entity.content_type = "application/xml"
|
22
|
+
|
23
|
+
@entity.to_request_data.should == "XML"
|
24
|
+
end
|
25
|
+
it "should be able to convert parameters into form_url_encoding" do
|
26
|
+
@entity.content_type = :form
|
27
|
+
|
28
|
+
@entity.to_request_data.split('&').sort.should == ["em-dashes=more+space%3Dgood","zoltan=Space+Emperor%21"]
|
29
|
+
end
|
30
|
+
it "should not attempt to coerce plain text into the requested format" do
|
31
|
+
@entity.content_type = :json
|
32
|
+
@entity.data = "{\"my_own\": \"data\"}"
|
33
|
+
|
34
|
+
@entity.to_request_data.should == "{\"my_own\": \"data\"}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require 'curb'
|
3
|
+
|
4
|
+
def regex_for_url_with_params(url, *params)
|
5
|
+
regex = '^' + url.gsub('/','\/').gsub('.','\.')
|
6
|
+
regex += '\?' unless params.empty?
|
7
|
+
|
8
|
+
unless params.empty?
|
9
|
+
param_possibilities = params.join('|')
|
10
|
+
regex += params.inject([]) { |list, param| list << "(#{param_possibilities})" }.join('&')
|
11
|
+
end
|
12
|
+
regex += '$'
|
13
|
+
Regexp.new(regex)
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestHarness
|
17
|
+
extend CurbFu::Request::Base
|
18
|
+
|
19
|
+
def self.create_post_fields(*args) # testing interface to private method #create_post_fields
|
20
|
+
super(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.create_put_fields(*args) # testing interface to private method #create_put_fields
|
24
|
+
super(*args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe CurbFu::Request::Base do
|
29
|
+
describe "build_url" do
|
30
|
+
it "should return a string if a string parameter is given" do
|
31
|
+
TestHarness.build_url("http://www.cliffsofinsanity.com").should == "http://www.cliffsofinsanity.com"
|
32
|
+
end
|
33
|
+
it "should return a built url with just a hostname if only the hostname is given" do
|
34
|
+
TestHarness.build_url(:host => "poisonedwine.com").should == "http://poisonedwine.com"
|
35
|
+
end
|
36
|
+
it "should return a built url with hostname and port if port is also given" do
|
37
|
+
TestHarness.build_url(:host => "www2.giantthrowingrocks.com", :port => 8080).
|
38
|
+
should == "http://www2.giantthrowingrocks.com:8080"
|
39
|
+
end
|
40
|
+
it "should return a built url with hostname, port, and path if all are given" do
|
41
|
+
TestHarness.build_url(:host => "spookygiantburningmonk.org", :port => 3000, :path => '/standing/in/a/wheelbarrow.aspx').
|
42
|
+
should == "http://spookygiantburningmonk.org:3000/standing/in/a/wheelbarrow.aspx"
|
43
|
+
end
|
44
|
+
it 'should append a query string if a query params hash is given' do
|
45
|
+
TestHarness.build_url('http://navyseals.mil', :swim_speed => '2knots').
|
46
|
+
should == 'http://navyseals.mil?swim_speed=2knots'
|
47
|
+
end
|
48
|
+
it 'should append a query string if a query string is given' do
|
49
|
+
TestHarness.build_url('http://chocolatecheese.com','?nuts=true').
|
50
|
+
should == 'http://chocolatecheese.com?nuts=true'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "get" do
|
55
|
+
it "should get the google" do
|
56
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil, :http_get => nil)
|
57
|
+
Curl::Easy.should_receive(:new).with('http://www.google.com').and_return(@mock_curb)
|
58
|
+
|
59
|
+
TestHarness.get("http://www.google.com")
|
60
|
+
end
|
61
|
+
it "should return a 404 code correctly" do
|
62
|
+
mock_curb = mock(Object, :http_get => nil)
|
63
|
+
TestHarness.stub!(:build).and_return(mock_curb)
|
64
|
+
mock_response = mock(CurbFu::Response::NotFound, :status => 404)
|
65
|
+
CurbFu::Response::Base.stub!(:from_curb_response).and_return(mock_response)
|
66
|
+
|
67
|
+
TestHarness.get("http://www.google.com/ponies_and_pirates").should == mock_response
|
68
|
+
end
|
69
|
+
it "should append query parameters" do
|
70
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil, :http_get => nil)
|
71
|
+
Curl::Easy.should_receive(:new).with(regex_for_url_with_params('http://www.google.com', 'search=MSU\+vs\+UNC', 'limit=200')).and_return(@mock_curb)
|
72
|
+
TestHarness.get('http://www.google.com', { :search => 'MSU vs UNC', :limit => 200 })
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "with_hash" do
|
76
|
+
it "should get google from {:host => \"www.google.com\", :port => 80}" do
|
77
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil, :http_get => nil)
|
78
|
+
Curl::Easy.should_receive(:new).with('http://www.google.com:80').and_return(@mock_curb)
|
79
|
+
|
80
|
+
TestHarness.get({:host => "www.google.com", :port => 80})
|
81
|
+
end
|
82
|
+
it "should set authorization username and password if provided" do
|
83
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil, :http_get => nil, :http_auth_types= => nil)
|
84
|
+
Curl::Easy.stub!(:new).and_return(@mock_curb)
|
85
|
+
@mock_curb.should_receive(:userpwd=).with("agent:donttellanyone")
|
86
|
+
|
87
|
+
TestHarness.get({:host => "secret.domain.com", :port => 80, :username => "agent", :password => "donttellanyone"})
|
88
|
+
end
|
89
|
+
it "should append parameters to the url" do
|
90
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil, :http_get => nil)
|
91
|
+
Curl::Easy.should_receive(:new).with(regex_for_url_with_params('http://www.google.com', 'search=MSU\+vs\+UNC', 'limit=200')).and_return(@mock_curb)
|
92
|
+
TestHarness.get({ :host => 'www.google.com' }, { :search => 'MSU vs UNC', :limit => 200 })
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "post" do
|
98
|
+
before(:each) do
|
99
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil)
|
100
|
+
Curl::Easy.stub!(:new).and_return(@mock_curb)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should send each parameter to Curb#http_post" do
|
104
|
+
@mock_q = Curl::PostField.content('q','derek')
|
105
|
+
@mock_r = Curl::PostField.content('r','matt')
|
106
|
+
TestHarness.stub!(:create_post_fields).and_return([@mock_q,@mock_r])
|
107
|
+
|
108
|
+
@mock_curb.should_receive(:http_post).with(@mock_q,@mock_r)
|
109
|
+
|
110
|
+
response = TestHarness.post(
|
111
|
+
{:host => "google.com", :port => 80, :path => "/search"},
|
112
|
+
{ 'q' => 'derek', 'r' => 'matt' })
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "post_file" do
|
117
|
+
it "should set encoding to multipart/form-data" do
|
118
|
+
@cc = mock(Curl::PostField)
|
119
|
+
Curl::PostField.stub!(:file).and_return(@cc)
|
120
|
+
mock_curl = mock(Object, :http_post => nil)
|
121
|
+
mock_curl.should_receive(:multipart_form_post=).with(true)
|
122
|
+
TestHarness.stub!(:build).and_return(mock_curl)
|
123
|
+
CurbFu::Response::Base.stub!(:from_curb_response)
|
124
|
+
|
125
|
+
TestHarness.post_file('http://example.com', {'gelato' => 'peanut butter'}, 'cc_pic' => '/images/credit_card.jpg')
|
126
|
+
end
|
127
|
+
it "should post with file fields" do
|
128
|
+
@cc = mock(Curl::PostField)
|
129
|
+
Curl::PostField.should_receive(:file).and_return(@cc)
|
130
|
+
mock_curl = mock(Object, :multipart_form_post= => nil, :http_post => nil)
|
131
|
+
TestHarness.stub!(:build).and_return(mock_curl)
|
132
|
+
CurbFu::Response::Base.stub!(:from_curb_response)
|
133
|
+
|
134
|
+
TestHarness.post_file('http://example.com', {'gelato' => 'peanut butter'}, 'cc_pic' => '/images/credit_card.jpg')
|
135
|
+
end
|
136
|
+
it "should offer more debug information about CurlErrInvalidPostField errors" do
|
137
|
+
@cc = mock(Curl::PostField)
|
138
|
+
Curl::PostField.should_receive(:file).and_return(@cc)
|
139
|
+
mock_curl = mock(Object, :multipart_form_post= => nil)
|
140
|
+
mock_curl.stub!(:http_post).and_raise(Curl::Err::InvalidPostFieldError)
|
141
|
+
TestHarness.stub!(:build).and_return(mock_curl)
|
142
|
+
CurbFu::Response::Base.stub!(:from_curb_response)
|
143
|
+
|
144
|
+
lambda { TestHarness.post_file('http://example.com', {'gelato' => 'peanut butter'}, 'cc_pic' => '/images/credit_card.jpg') }.
|
145
|
+
should raise_error(Curl::Err::InvalidPostFieldError)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "put" do
|
150
|
+
before(:each) do
|
151
|
+
@mock_curb = mock(Curl::Easy, :headers= => nil, :headers => {}, :header_str => "", :response_code => 200, :body_str => 'yeeeah', :timeout= => nil)
|
152
|
+
Curl::Easy.stub!(:new).and_return(@mock_curb)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should send each parameter to Curb#http_put" do
|
156
|
+
Curl::Easy.should_receive(:new).with('http://google.com:80/search?q=derek&r=matt').and_return(@mock_curb)
|
157
|
+
@mock_curb.should_receive(:http_put)
|
158
|
+
|
159
|
+
response = TestHarness.put(
|
160
|
+
{:host => "google.com", :port => 80, :path => "/search"},
|
161
|
+
{ 'q' => 'derek', 'r' => 'matt' })
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "create_post_fields" do
|
166
|
+
it "should return the params if params is a string" do
|
167
|
+
TestHarness.create_post_fields("my awesome data that I'm sending to you").
|
168
|
+
should == "my awesome data that I'm sending to you"
|
169
|
+
end
|
170
|
+
it "should convert hash items into Curl::PostFields" do
|
171
|
+
Curl::PostField.should_receive(:content).with('us','obama')
|
172
|
+
Curl::PostField.should_receive(:content).with('de','merkel')
|
173
|
+
TestHarness.create_post_fields(:us => 'obama', :de => 'merkel')
|
174
|
+
end
|
175
|
+
it "should handle params that contain arrays" do
|
176
|
+
Curl::PostField.should_receive(:content).with('q','derek,matt')
|
177
|
+
|
178
|
+
TestHarness.create_post_fields('q' => ['derek','matt'])
|
179
|
+
end
|
180
|
+
it "should handle params that contain any non-Array or non-String data" do
|
181
|
+
Curl::PostField.should_receive(:content).with('q','1')
|
182
|
+
|
183
|
+
TestHarness.create_post_fields('q' => 1)
|
184
|
+
end
|
185
|
+
it "should return an array of Curl::PostFields" do
|
186
|
+
TestHarness.create_post_fields(:ice_cream => 'chocolate', :beverage => 'water').each do |field|
|
187
|
+
field.should be_a_kind_of(Curl::PostField)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe "create_put_fields" do
|
193
|
+
it "should return the params if params is a string" do
|
194
|
+
TestHarness.create_put_fields("my awesome data that I'm sending to you").
|
195
|
+
should == "my awesome data that I'm sending to you"
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should handle multiple parameters' do
|
199
|
+
TestHarness.create_put_fields(:rock => 'beatles', :rap => '2pac').
|
200
|
+
should == "rock=beatles&rap=2pac"
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should handle params that contain arrays" do
|
204
|
+
TestHarness.create_put_fields('q' => ['derek','matt']).
|
205
|
+
should == "q=derek,matt"
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should handle params that contain any non-Array or non-String data" do
|
209
|
+
TestHarness.create_put_fields('q' => 1).should == "q=1"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "global_headers" do
|
214
|
+
it "should use any global headers for every request" do
|
215
|
+
TestHarness.global_headers = {
|
216
|
+
'X-Http-Modern-Parlance' => 'Transmogrify'
|
217
|
+
}
|
218
|
+
|
219
|
+
mock_curl = mock(Object, :timeout= => 'sure', :http_get => 'uhuh', :response_code => 200, :header_str => 'yep: sure', :body_str => 'ok')
|
220
|
+
Curl::Easy.stub!(:new).and_return(mock_curl)
|
221
|
+
mock_curl.should_receive(:headers=).with('X-Http-Modern-Parlance' => 'Transmogrify')
|
222
|
+
TestHarness.get('http://example.com')
|
223
|
+
end
|
224
|
+
it "should not keep temporary headers from previous requests" do
|
225
|
+
TestHarness.global_headers = {
|
226
|
+
'X-Http-Political-Party' => 'republican'
|
227
|
+
}
|
228
|
+
|
229
|
+
mock_curl = mock(Object, :timeout= => 'sure', :http_get => 'uhuh', :response_code => 200, :header_str => 'yep: sure', :body_str => 'ok')
|
230
|
+
Curl::Easy.stub!(:new).and_return(mock_curl)
|
231
|
+
mock_curl.stub!(:headers=)
|
232
|
+
|
233
|
+
TestHarness.get(:host => 'example.com', :headers => { 'Content-Type' => 'cash/dollars' })
|
234
|
+
|
235
|
+
mock_curl.should_not_receive(:headers=).with(hash_including('Content-Type' => 'cash/dollars'))
|
236
|
+
TestHarness.get('http://example.com')
|
237
|
+
TestHarness.global_headers.should_not include('Content-Type' => 'cash/dollars') # leave no trace!
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|