# -*- coding: UTF-8 -*- # Encoding pragma is needed for loading this test properly on Ruby < 2.0 ## ------------------------------------------------------------------- ## ## Copyright (c) 2009 Phillip Toland ## ## Permission is hereby granted, free of charge, to any person obtaining a copy ## of this software and associated documentation files (the "Software"), to deal ## in the Software without restriction, including without limitation the rights ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ## copies of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## ## The above copyright notice and this permission notice shall be included in ## all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ## THE SOFTWARE. ## ## ------------------------------------------------------------------- require File.expand_path("./spec") + '/spec_helper.rb' require 'webrick' require 'base64' require 'fileutils' describe Patron::Response do around(:each) do |example| previous_internal = Encoding.default_internal example.run Encoding.default_internal = previous_internal end before(:each) do @session = Patron::Session.new @session.base_url = "http://localhost:9001" end it 'recovers the status code' do response = @session.get("/repetitiveheader") expect(response.status).to be_kind_of(Integer) expect(response.status).to eq(200) end it 'saves the definitive URL in the url attribute' do headers = "HTTP/1.1 200 OK \r\nContent-Type: text/plain\r\n" response = Patron::Response.new("http://example.com/url", 200, 0, headers, '', "UTF-8") expect(response.url).to eq("http://example.com/url") end it 'parses the status code and supports ok? and error?' do headers = "HTTP/1.1 200 OK \r\nContent-Type: text/plain\r\n" body = "abc" response = Patron::Response.new("url", 200, 0, headers, body, "UTF-8") expect(response.status).to eq(200) expect(response).to be_ok expect(response).not_to be_error headers = "HTTP/1.1 400 Bad Request \r\nContent-Type: text/plain\r\n" body = "abc" response = Patron::Response.new("url", 400, 0, headers, body, "UTF-8") expect(response.status).to eq(400) expect(response).not_to be_ok expect(response).to be_error end it "should strip extra spaces from header values" do response = @session.get("/test") # All digits, no spaces expect(response.headers['Content-Length']).to match(/^\d+$/) end it "should return an array of values when multiple header fields have same name" do response = @session.get("/repetitiveheader") expect(response.headers['Set-Cookie']).to be == ["a=1","b=2"] end describe '#decoded_body and #inspectable_body' do it "should raise with explicitly binary response bodies but allow an inspectable body" do Encoding.default_internal = Encoding::UTF_8 response = @session.get("/picture") expect(response.headers['Content-Type']).to be == 'image/png' expect(response.body.encoding).to be == Encoding::BINARY expect(response).not_to be_body_decodable expect { response.decoded_body }.to raise_error(Patron::NonRepresentableBody) inspectable = response.inspectable_body expect(inspectable.encoding).to eq(Encoding::UTF_8) expect(inspectable).to be_valid_encoding end it "should encode body in the internal charset" do allow(Encoding).to receive(:default_internal).and_return("UTF-8") greek_encoding = Encoding.find("ISO-8859-7") utf_encoding = Encoding.find("UTF-8") headers = "HTTP/1.1 200 OK \r\nContent-Type: text/css;charset=ISO-8859-7\r\n" body = "Ππ".encode(greek_encoding) # Greek alphabet response = Patron::Response.new("url", "status", 0, headers, body, nil) expect(response).to be_body_decodable expect(response.decoded_body.encoding).to eql(utf_encoding) end it "should fallback to default charset when header or body charset is not valid" do allow(Encoding).to receive(:default_internal).and_return("UTF-8") encoding = Encoding.find("UTF-8") headers = "HTTP/1.1 200 OK \r\nContent-Type: text/css; charset=invalid\r\n" body = "who knows which encoding this CSS is in?" response = Patron::Response.new("url", "status", 0, headers, body, "UTF-8") expect(response.charset).to eq('invalid') expect(response).not_to be_body_decodable expect { response.decoded_body }.to raise_error(Patron::HeaderCharsetInvalid) end end it "decodes a header that contains UTF-8 even though internal encoding is ASCII" do Encoding.default_internal = Encoding::ASCII encoding = Encoding.find("UTF-8") headers = "HTTP/1.1 200 OK \r\nContent-Disposition: attachment,filename=\"žфайлец.txt\"\r\n" body = "this is a file with a Russian filename set in content-disposition" response = Patron::Response.new("url", "status", 0, headers, body, "UTF-8") dispo = response.headers['Content-Disposition'] expect(dispo.encoding).to eq(Encoding::UTF_8) end it "should be able to serialize and deserialize itself" do expect(Marshal.load(Marshal.dump(@request))).to eql(@request) end end