curb-fu 0.4.3
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/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
|