spec/motion/http_spec.rb in bubble-wrap-1.1.2 vs spec/motion/http_spec.rb in bubble-wrap-1.1.3

- old
+ new

@@ -1,9 +1,10 @@ describe "HTTP" do before do @localhost_url = 'http://localhost' + @fake_url = 'http://fake.url' end describe "Core HTTP method calls" do def test_http_method(method) @@ -25,36 +26,34 @@ [:get, :post, :put, :delete, :head, :patch].each do |method| test_http_method method end end - it "uses the block instead of action passed in " do + it "uses the block instead of :action if both were given" do [:get, :post, :put, :delete, :head, :patch].each do |method| called = false expected_delegator = Proc.new {|response| called = true } query = BubbleWrap::HTTP.send(method, @localhost_url, { action: 'not_valid' }, &expected_delegator) + query.connectionDidFinishLoading(query.connection) + query.instance_variable_get(:@delegator).should.equal expected_delegator + called.should.equal true + end + end + + it "works with classic blocks as well" do + [:get, :post, :put, :delete, :head, :patch].each do |method| + called = false + query = BubbleWrap::HTTP.send(method, @localhost_url, { action: 'not_valid' } ) do |response| + called = true + end query.connectionDidFinishLoading(query.connection) called.should.equal true end end - # [:get, :post, :put, :delete, :head, :patch].each do |verb| - # it "has access to the proper response scope for #{verb} request" do - # class WatchedObj; attr_accessor :test_value end - # @watched_object = WatchedObj.new - # @name = 'Matt' - # query = BubbleWrap::HTTP.send(verb, @localhost_url) do |response| - # @watched_object.test_value = @name - # end - # wait_for_change(@watched_object, 'test_value') do - # @watched_object.test_value.should == 'Matt' - # end - # end - # end - end describe "HTTP::Response" do before do @@ -105,11 +104,11 @@ twitter: '@mneorr', website: 'mneorr.com', values: ['apple', 'orange', 'peach'], credentials: @credentials } - @action = lambda{|fa, ke|} + @action = Proc.new { |response| @real_response = response; @delegator_was_called = true } @format = "application/x-www-form-urlencoded" @cache_policy = 24234 @leftover_option = 'trololo' @headers = { 'User-Agent' => "Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \n Gecko/20100101 Firefox/12.0" } @files = { @@ -148,10 +147,22 @@ it "should upcase the HTTP method" do @query.method.should.equal "GET" end + it "throws an error for invalid/missing URL schemes" do + %w(http https file ftp).each do |scheme| + lambda { + BW::HTTP::Query.new("#{scheme}://example.com", :get) { |r| p r.body.to_str } + }.should.not.raise InvalidURLError + end + + lambda { + BW::HTTP::Query.new("bad://example.com", :get) { |r| p r.body.to_str } + }.should.raise InvalidURLError + end + it "should set the deleted delegator from options" do @query.instance_variable_get(:@delegator).should.equal @action @options.should.not.has_key? :action end @@ -183,11 +194,11 @@ describe "PAYLOAD / UPLOAD FILES" do def create_query(payload, files) - BubbleWrap::HTTP::Query.new( '', :post, { payload: payload, files: files } ) + BubbleWrap::HTTP::Query.new( 'http://haha', :post, { payload: payload, files: files } ) end def sample_data "twitter:@mneorr".dataUsingEncoding NSUTF8StringEncoding end @@ -197,17 +208,17 @@ @query.instance_variable_get(:@payload).should.equal payload @options.should.not.has_key? :payload end it "should check if @payload is a hash before generating GET params" do - query_string_payload = BubbleWrap::HTTP::Query.new( 'nil' , :get, { payload: "name=apple&model=macbook"} ) + query_string_payload = BubbleWrap::HTTP::Query.new( @fake_url , :get, { payload: "name=apple&model=macbook"} ) query_string_payload.instance_variable_get(:@payload).should.equal 'name=apple&model=macbook' end it "should check if payload is nil" do lambda{ - BubbleWrap::HTTP::Query.new( 'nil' , :post, {} ) + BubbleWrap::HTTP::Query.new( @fake_url , :post, {} ) }.should.not.raise NoMethodError end it "should set the payload in URL only for GET and HEAD requests" do [:post, :put, :delete, :patch].each do |method| @@ -227,19 +238,19 @@ files = { twitter: sample_data, site: "mneorr.com".dataUsingEncoding(NSUTF8StringEncoding) } puts "\n" [:post, :put, :delete, :patch].each do |method| puts " - #{method}\n" - query = BubbleWrap::HTTP::Query.new( 'nil' , method, { payload: payload, files: files } ) + query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: payload, files: files } ) uuid = query.instance_variable_get(:@boundary) real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding) - real_payload.should.equal "\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nmacbook\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"twitter\"; filename=\"twitter\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"site\"; filename=\"site\"\r\nContent-Type: application/octet-stream\r\n\r\nmneorr.com\r\n--#{uuid}--\r\n" + real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nmacbook\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"twitter\"; filename=\"twitter\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"site\"; filename=\"site\"\r\nContent-Type: application/octet-stream\r\n\r\nmneorr.com\r\n--#{uuid}--\r\n" end [:get, :head].each do |method| puts " - #{method}\n" - query = BubbleWrap::HTTP::Query.new( 'nil' , method, { payload: payload } ) + query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: payload } ) real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding) real_payload.should.be.empty end end @@ -247,26 +258,26 @@ data = sample_data lambda { query = create_query(data, nil) }.should.not.raise NoMethodError end it "sets the payload as a string if JSON" do - json = BW::JSON.generate({foo:42, bar:'BubbleWrap'}) - puts "\n" + json = "{\"foo\":42,\"bar\":\"BubbleWrap\"}" + puts "\n" [:put, :post, :delete, :patch].each do |method| puts " - #{method}\n" - query = BubbleWrap::HTTP::Query.new( 'nil' , method, { payload: json } ) + query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: json } ) set_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding) set_payload.should.equal json end end it "sets the payload for a nested hash to multiple form-data parts" do payload = { computer: { name: 'apple', model: 'macbook'} } - query = BubbleWrap::HTTP::Query.new( 'nil', :post, { payload: payload } ) + query = BubbleWrap::HTTP::Query.new( @fake_url, :post, { payload: payload } ) uuid = query.instance_variable_get(:@boundary) real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding) - real_payload.should.equal "\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[name]\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[model]\"\r\n\r\nmacbook\r\n--#{uuid}--\r\n" + real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[name]\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"computer[model]\"\r\n\r\nmacbook\r\n--#{uuid}--\r\n" end end it "should set default timeout to 30s or the one from hash" do @@ -278,11 +289,11 @@ new_query.instance_variable_get(:@timeout).should == 10 options.should.be.empty end it "should delete :headers from options and escape Line Feeds" do - escaped_lf = {"User-Agent"=>"Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \\n Gecko/20100101 Firefox/12.0"} + escaped_lf = {"User-Agent"=>"Mozilla/5.0 (X11; Linux x86_64; rv:12.0) \r\n Gecko/20100101 Firefox/12.0"} @query.instance_variable_get(:@headers).should.equal escaped_lf end it "should delete :cache_policy or set NSURLRequestUseProtocolCachePolicy" do @query.instance_variable_get(:@cache_policy).should.equal @cache_policy @@ -336,16 +347,16 @@ it "creates a new NSURLConnection and sets itself as a delegate" do @query.connection.delegate.should.equal @query end it "should patch the NSURLRequest with done_loading and done_loading!" do - @query.request.done_loading.should.equal @query.request.instance_variable_get(:@done_loading) + @query.request.done_loading?.should.equal @query.request.instance_variable_get(:@done_loading) @query.request.instance_variable_set(:@done_loading, false) - @query.request.done_loading.should.equal false + @query.request.done_loading?.should.equal false @query.request.done_loading! - @query.request.done_loading.should.equal true + @query.request.done_loading?.should.equal true end it "should pass the right arguments when creating new request" do @query.request.cachePolicy.should.equal @query.instance_variable_get(:@cache_policy) @query.request.timeoutInterval.should.equal @query.instance_variable_get(:@timeout) @@ -360,10 +371,15 @@ @headers = { fake: 'headers' } @payload = { key:'abc1234' } @post_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, payload: @payload}) end + it "should add default Content Type if no payload is given" do + query_without_payload = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers}) + query_without_payload.request.allHTTPHeaderFields.should.include? 'Content-Type' + end + it "should automatically provide Content-Type if a payload is provided" do @post_query.request.allHTTPHeaderFields.should.include?('Content-Type') end it "should use the format parameter to decide the Content-Type" do @@ -386,15 +402,10 @@ @headers = { fake: 'headers', 'CONTENT-TYPE' => 'x-banana' } @post_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers, payload: @payload}) @post_query.request.allHTTPHeaderFields['CONTENT-TYPE'].should.equal @headers['CONTENT-TYPE'] end - it "should not add additional headers if no payload is given" do - @post_query = BubbleWrap::HTTP::Query.new(@url_string, :post, {headers: @headers}) - @post_query.request.allHTTPHeaderFields.should.equal @headers - end - end describe "Generating payloads" do it "should create payload key/value pairs from nested hashes with prefix[key]=value" do @@ -465,13 +476,13 @@ @query.connection(nil, didFailWithError:@fake_error) UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == false end it "should set request_done to true" do - @query.request.done_loading.should == false + @query.request.done_loading?.should == false @query.connection(nil, didFailWithError:@fake_error) - @query.request.done_loading.should == true + @query.request.done_loading?.should == true end it "should set the error message to response object" do @query.response.error_message.should.equal nil @query.connection(nil, didFailWithError:@fake_error) @@ -500,14 +511,14 @@ @query.connectionDidFinishLoading(nil) UIApplication.sharedApplication.isNetworkActivityIndicatorVisible.should == false end it "should set request_done to true" do - @query.request.done_loading.should == false + @query.request.done_loading?.should == false @query.connectionDidFinishLoading(nil) - @query.request.done_loading.should == true + @query.request.done_loading?.should == true end it "should set response_body to @received data if not nil" do data = NSData.dataWithBytesNoCopy(Pointer.new(:char, 'abc'), length:24) headers = { foo: 'bar' } @@ -537,38 +548,39 @@ end describe "when connection:willSendRequest:redirectResponse:" do before do - @request = NSURLRequest.requestWithURL NSURL.URLWithString('http://fakehost.local/') + @request = NSMutableURLRequest.requestWithURL NSURL.URLWithString('http://fakehost.local/') end - it "should make a mutableCopy of passed in request and set headers from @headers" do - expected_headers = { new_header: 'should_be_here' } - @query.instance_variable_set(:@headers, expected_headers) + it "should forward the new request for 30 times/redirections" do + 1.upto(35) do |numbah| + request = @query.connection(nil, willSendRequest:@request, redirectResponse:nil) + request.should.equal numbah < 30 ? @request : nil + end + end - new_request = @query.connection(nil, willSendRequest:@request, redirectResponse:nil) + describe "after 30 redirects" do + before do + 31.times do + @query.connection(nil, willSendRequest:@request, redirectResponse:nil) + end + end - @query.request.should.not.be.equal @request - new_request.URL.description.should.equal @request.URL.description - new_request.allHTTPHeaderFields.should.equal expected_headers - end + it "sets the error message on response" do + @real_response.error_message.should.equal "Too many redirections" + end - it "should create a new Connection with the request passed in" do - old_connection = @query.connection - @query.connection(nil, willSendRequest:@request, redirectResponse:nil) - old_connection.should.not.equal @query.connection - end + it "sets the request.done_loading" do + @query.request.done_loading?.should.equal true + end - it "should set itself as a delegate of new NSURLConnection" do - @query.connection(nil, willSendRequest:@request, redirectResponse:nil) - @query.connection.delegate.should.equal @query + it "calls the delegator block" do + @delegator_was_called.should.equal true + end end - it "should pass the new request in the new connection" do - @query.connection(nil, willSendRequest:@request, redirectResponse:nil) - @query.connection.request.URL.description.should.equal @request.URL.description - end end describe "didReceiveAuthenticationChallenge" do before do @challenge = FakeChallenge.new