require "spec_helper"
describe Savon::SOAP::XML do
def xml(endpoint = nil, input = nil, body = nil)
@xml ||= begin
xml = Savon::SOAP::XML.new(config)
xml.endpoint = endpoint || Endpoint.soap
xml.input = input || [nil, :authenticate, {}]
xml.body = body || { :id => 1 }
xml
end
end
let(:config) { Savon::Config.default }
describe "#input" do
it "should set the input tag" do
xml.input = :test
xml.input.should == :test
end
end
describe "#endpoint" do
it "should set the endpoint to use" do
xml.endpoint = "http://test.com"
xml.endpoint.should == "http://test.com"
end
end
describe "#version" do
it "should default to SOAP 1.1" do
xml.version.should == 1
end
it "should default to the global default" do
config.soap_version = 2
xml.version.should == 2
end
it "should set the SOAP version to use" do
xml.version = 2
xml.version.should == 2
end
it "should raise an ArgumentError in case of an invalid version" do
lambda { xml.version = 3 }.should raise_error(ArgumentError)
end
end
describe "#header" do
it "should default to an empty Hash" do
xml.header.should == {}
end
it "should set the SOAP header" do
xml.header = { "MySecret" => "abc" }
xml.header.should == { "MySecret" => "abc" }
end
it "should use the global soap_header if set" do
config.stubs(:soap_header).returns({ "MySecret" => "abc" })
xml.header.should == { "MySecret" => "abc" }
end
end
describe "#env_namespace" do
it "should default to :env" do
xml.env_namespace.should == :env
end
it "should set the SOAP envelope namespace" do
xml.env_namespace = :soapenv
xml.env_namespace.should == :soapenv
end
it "should use the global env_namespace if set as the SOAP envelope namespace" do
config.stubs(:env_namespace).returns(:soapenv)
xml.env_namespace.should == :soapenv
end
end
describe "#namespaces" do
it "should default to a Hash containing the namespace for SOAP 1.1" do
xml.namespaces.should == { "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/" }
end
it "should default to a Hash containing the namespace for SOAP 1.2 if that's the current version" do
xml.version = 2
xml.namespaces.should == { "xmlns:env" => "http://www.w3.org/2003/05/soap-envelope" }
end
it "should set the SOAP header" do
xml.namespaces = { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
xml.namespaces.should == { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
end
end
describe "#wsse" do
it "should set the Akami::WSSE object" do
xml.wsse = Akami.wsse
xml.wsse.should be_a(Akami::WSSE)
end
end
describe "#body" do
it "should set the SOAP body Hash" do
xml.body = { :id => 1 }
xml.to_xml.should include("1")
end
it "should accepts an XML String" do
xml.body = "1"
xml.to_xml.should include("1")
end
it "should accept a block" do
xml.body do |body|
body.user { body.id 1 }
end
xml.to_xml.should include("1")
end
end
describe "#encoding" do
it "defaults to UTF-8" do
xml.encoding.should == "UTF-8"
end
end
describe "#xml" do
it "lets you specify a completely custom XML String" do
xml.xml = "xml"
xml.to_xml.should == "xml"
end
it "yields a Builder::XmlMarkup object to a given block" do
xml.xml { |xml| xml.using("Builder") }
xml.to_xml.should == 'Builder'
end
it "accepts options to pass to the Builder::XmlMarkup instruct!" do
xml.xml :xml, :aaa => :bbb do |xml|
xml.using("Builder")
end
xml.to_xml.should == 'Builder'
end
it "allows to change the encoding" do
xml.xml(:xml, :encoding => "US-ASCII") { |xml| xml.using("Builder") }
xml.to_xml.should == 'Builder'
end
end
describe "#to_xml" do
context "by default" do
it "should start with an XML declaration" do
xml.to_xml.should match(/^<\?xml version="1.0" encoding="UTF-8"\?>/)
end
it "should use default SOAP envelope namespace" do
xml.to_xml.should include("/)
end
it "should add the xsi namespace" do
uri = "http://www.w3.org/2001/XMLSchema-instance"
xml.to_xml.should match(//)
end
it "should have a SOAP envelope tag with a SOAP 1.1 namespace" do
uri = "http://schemas.xmlsoap.org/soap/envelope/"
xml.to_xml.should match(//)
end
it "should have a SOAP body containing the SOAP input tag and body Hash" do
xml.to_xml.should include('1')
end
it "should accept a SOAP body as an XML String" do
xml.body = "1"
xml.to_xml.should include('1')
end
it "should not contain a SOAP header" do
xml.to_xml.should_not include('/)
end
end
context "with a SOAP header" do
context "as a Hash" do
it "should contain the given header" do
xml.header = {
:token => "secret",
:attributes! => { :token => { :xmlns => "http://example.com" } }
}
xml.to_xml.should include('secret')
end
end
context "as a String" do
it "should contain the given header" do
xml.header = %{secret}
xml.to_xml.should include('secret')
end
end
end
context "with the global SOAP version set to 1.2" do
it "should contain the namespace for SOAP 1.2" do
config.soap_version = 2
uri = "http://www.w3.org/2003/05/soap-envelope"
xml.to_xml.should match(//)
end
end
context "with a global and request SOAP version" do
it "should contain the namespace for the request SOAP version" do
config.soap_version = 2
xml.version = 1
uri = "http://schemas.xmlsoap.org/soap/envelope/"
xml.to_xml.should match(//)
end
end
context "with the SOAP envelope namespace set to an empty String" do
it "should not add a namespace to SOAP envelope tags" do
xml.env_namespace = ""
xml.to_xml.should include(" { :id => 1, ":noNamespace" => true })
xml.element_form_default = :qualified
xml.namespace_identifier = :wsdl
xml.to_xml.should include("", "1", "true")
end
end
context "with :element_form_default set to :unqualified and a :namespace" do
it "should namespace the default elements" do
xml = xml(Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true })
xml.element_form_default = :unqualified
xml.namespace_identifier = :wsdl
xml.to_xml.should include("", "1", "true")
end
end
context "with WSSE authentication" do
it "should containg a SOAP header with WSSE authentication details" do
xml.wsse = Akami.wsse
xml.wsse.credentials "username", "password"
xml.to_xml.should include("username")
xml.to_xml.should include("password")
end
end
context "with a simple input tag (Symbol)" do
it "should just add the input tag" do
xml.input = [nil, :simple, {}]
xml.to_xml.should include('1')
end
end
context "with a simple input tag (Array)" do
it "should just add the input tag" do
xml.input = [nil, :simple, {}]
xml.to_xml.should include('1')
end
end
context "with an input tag and a namespace Hash (Array)" do
it "should contain the input tag with namespaces" do
xml.input = [nil, :getUser, { "active" => true }]
xml.to_xml.should include('1')
end
end
context "with a prefixed input tag (Array)" do
it "should contain a prefixed input tag" do
xml.input = [:wsdl, :getUser, {}]
xml.to_xml.should include('1')
end
end
context "with a prefixed input tag and a namespace Hash (Array)" do
it "should contain a prefixed input tag with namespaces" do
xml.input = [:wsdl, :getUser, { :only_active => false }]
xml.to_xml.should include('1')
end
end
end
describe "#add_namespaces_to_body" do
before :each do
xml.used_namespaces.merge!({
["authenticate", "id"] =>"ns0",
["authenticate", "name"] =>"ns1",
["authenticate", "name", "firstName"] =>"ns2"
})
end
it "adds namespaces" do
body = {:id => 1, :name => {:first_name => 'Bob'}}
xml.send(:add_namespaces_to_body, body).should == {"ns0:id" => "1", "ns1:name" => {"ns2:firstName" => "Bob"}}
end
it "adds namespaces to order! list" do
body = {:id => 1, :name => {:first_name => 'Bob', :order! => [:first_name]}, :order! => [:id, :name]}
xml.send(:add_namespaces_to_body, body).should == {
"ns0:id" => "1",
"ns1:name" => {
"ns2:firstName" => "Bob",
:order! => ["ns2:firstName"]
},
:order! => ["ns0:id", "ns1:name"]
}
end
end
end