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.
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'curb-fu/test/server'
2
+ require 'curb-fu/test/request_logger'
3
+
4
+ module CurbFu
5
+ module Test; end
6
+ end
@@ -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