require "spec_helper" describe Savon::Response do let(:globals) { Savon::GlobalOptions.new } let(:locals) { Savon::LocalOptions.new } describe ".new" do it "should raise a Savon::Fault in case of a SOAP fault" do expect { soap_fault_response }.to raise_error(Savon::SOAPFault) end it "should not raise a Savon::Fault in case the default is turned off" do globals[:raise_errors] = false expect { soap_fault_response }.not_to raise_error end it "should raise a Savon::HTTP::Error in case of an HTTP error" do expect { soap_response :code => 500 }.to raise_error(Savon::HTTPError) end it "should not raise a Savon::HTTP::Error in case the default is turned off" do globals[:raise_errors] = false soap_response :code => 500 end end describe "#success?" do before { globals[:raise_errors] = false } it "should return true if the request was successful" do expect(soap_response).to be_a_success end it "should return false if there was a SOAP fault" do expect(soap_fault_response).not_to be_a_success end it "should return false if there was an HTTP error" do expect(http_error_response).not_to be_a_success end end describe "#soap_fault?" do before { globals[:raise_errors] = false } it "should not return true in case the response seems to be ok" do expect(soap_response.soap_fault?).to be_falsey end it "should return true in case of a SOAP fault" do expect(soap_fault_response.soap_fault?).to be_truthy end end describe "#soap_fault" do before { globals[:raise_errors] = false } it "should return nil in case the response seems to be ok" do expect(soap_response.soap_fault).to be_nil end it "should return a SOAPFault in case of a SOAP fault" do expect(soap_fault_response.soap_fault).to be_a(Savon::SOAPFault) end end describe "#http_error?" do before { globals[:raise_errors] = false } it "should not return true in case the response seems to be ok" do expect(soap_response.http_error?).not_to be_truthy end it "should return true in case of an HTTP error" do expect(soap_response(:code => 500).http_error?).to be_truthy end end describe "#http_error" do before { globals[:raise_errors] = false } it "should return nil in case the response seems to be ok" do expect(soap_response.http_error).to be_nil end it "should return a HTTPError in case of an HTTP error" do expect(soap_response(:code => 500).http_error).to be_a(Savon::HTTPError) end end describe "#header" do it "should return the SOAP response header as a Hash" do response = soap_response :body => Fixture.response(:header) expect(response.header).to include(:session_number => "ABCD1234") end it 'respects the global :strip_namespaces option' do globals[:strip_namespaces] = false response_with_header = soap_response(:body => Fixture.response(:header)) header = response_with_header.header expect(header).to be_a(Hash) # notice: :session_number is a snake_case Symbol without namespaces, # but the Envelope and Header elements are qualified. expect(header.keys).to include(:session_number) end it 'respects the global :convert_response_tags_to option' do globals[:convert_response_tags_to] = lambda { |key| key.upcase } response_with_header = soap_response(:body => Fixture.response(:header)) header = response_with_header.header expect(header).to be_a(Hash) expect(header.keys).to include('SESSIONNUMBER') end it 'respects the global :convert_attributes_to option' do globals[:convert_attributes_to] = lambda { |k,v| [] } response_with_header = soap_response(:body => Fixture.response(:header)) header = response_with_header.header expect(header).to be_a(Hash) expect(header.keys).to include(:session_number) end it "should throw an exception when the response header isn't parsable" do expect { invalid_soap_response.header }.to raise_error Savon::InvalidResponseError end end %w(body to_hash).each do |method| describe "##{method}" do it "should return the SOAP response body as a Hash" do expect(soap_response.send(method)[:authenticate_response][:return]).to eq( Fixture.response_hash(:authentication)[:authenticate_response][:return] ) end it "should return a Hash for a SOAP multiRef response" do hash = soap_response(:body => Fixture.response(:multi_ref)).send(method) expect(hash[:list_response]).to be_a(Hash) expect(hash[:multi_ref]).to be_an(Array) end it "should add existing namespaced elements as an array" do hash = soap_response(:body => Fixture.response(:list)).send(method) expect(hash[:multi_namespaced_entry_response][:history]).to be_a(Hash) expect(hash[:multi_namespaced_entry_response][:history][:case]).to be_an(Array) end it 'respects the global :strip_namespaces option' do globals[:strip_namespaces] = false body = soap_response.body expect(body).to be_a(Hash) expect(body.keys).to include(:"ns2:authenticate_response") end it 'respects the global :convert_response_tags_to option' do globals[:convert_response_tags_to] = lambda { |key| key.upcase } body = soap_response.body expect(body).to be_a(Hash) expect(body.keys).to include('AUTHENTICATERESPONSE') end end end describe "#to_array" do context "when the given path exists" do it "should return an Array containing the path value" do expect(soap_response.to_array(:authenticate_response, :return)).to eq( [Fixture.response_hash(:authentication)[:authenticate_response][:return]] ) end it "should properly return FalseClass values [#327]" do body = Gyoku.xml(:envelope => { :body => { :return => { :success => false } } }) expect(soap_response(:body => body).to_array(:return, :success)).to eq([false]) end end context "when the given path returns nil" do it "should return an empty Array" do expect(soap_response.to_array(:authenticate_response, :undefined)).to eq([]) end end context "when the given path does not exist at all" do it "should return an empty Array" do expect(soap_response.to_array(:authenticate_response, :some, :undefined, :path)).to eq([]) end end end describe "#hash" do it "should return the complete SOAP response XML as a Hash" do response = soap_response :body => Fixture.response(:header) expect(response.hash[:envelope][:header][:session_number]).to eq("ABCD1234") end end describe "#to_xml" do it "should return the raw SOAP response body" do expect(soap_response.to_xml).to eq(Fixture.response(:authentication)) end end describe "#doc" do it "returns a Nokogiri::XML::Document for the SOAP response XML" do expect(soap_response.doc).to be_a(Nokogiri::XML::Document) end end describe "#xpath" do it "permits XPath access to elements in the request" do expect(soap_response.xpath("//client").first.inner_text).to eq("radclient") expect(soap_response.xpath("//ns2:authenticateResponse/return/success").first.inner_text).to eq("true") end end describe '#find' do it 'delegates to Nori#find to find child elements inside the Envelope' do result = soap_response.find('Body', 'authenticateResponse', 'return') expect(result).to be_a(Hash) expect(result.keys).to include(:authentication_value) end end describe "#http" do it "should return the HTTPI::Response" do expect(soap_response.http).to be_an(HTTPI::Response) end end def soap_response(options = {}) defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) } response = defaults.merge options http_response = HTTPI::Response.new(response[:code], response[:headers], response[:body]) Savon::Response.new(http_response, globals, locals) end def soap_fault_response soap_response :code => 500, :body => Fixture.response(:soap_fault) end def http_error_response soap_response :code => 404, :body => "Not found" end def invalid_soap_response(options = {}) defaults = { :code => 200, :headers => {}, :body => "I'm not SOAP" } response = defaults.merge options http_response = HTTPI::Response.new(response[:code], response[:headers], response[:body]) Savon::Response.new(http_response, globals, locals) end end