savon 1.1.0 → 1.2.0
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.
- data/CHANGELOG.md +127 -67
 - data/lib/savon/client.rb +62 -83
 - data/lib/savon/http/error.rb +1 -1
 - data/lib/savon/soap/request_builder.rb +205 -0
 - data/lib/savon/soap/xml.rb +1 -1
 - data/lib/savon/version.rb +1 -1
 - data/spec/fixtures/wsdl/multiple_namespaces.xml +31 -0
 - data/spec/integration/request_spec.rb +50 -11
 - data/spec/savon/client_spec.rb +181 -104
 - data/spec/savon/http/error_spec.rb +1 -1
 - data/spec/savon/soap/fault_spec.rb +1 -1
 - data/spec/savon/soap/request_builder_spec.rb +207 -0
 - metadata +42 -40
 - data/lib/savon/wasabi/document.rb +0 -47
 - data/spec/savon/wasabi/document_spec.rb +0 -58
 
    
        data/lib/savon/http/error.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,205 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Savon
         
     | 
| 
      
 2 
     | 
    
         
            +
              module SOAP
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                # = Savon::SOAP::RequestBuilder
         
     | 
| 
      
 5 
     | 
    
         
            +
                #
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Savon::SOAP::RequestBuilder builds Savon::SOAP::Request instances.
         
     | 
| 
      
 7 
     | 
    
         
            +
                # The RequestBuilder is configured by the client that instantiates it.
         
     | 
| 
      
 8 
     | 
    
         
            +
                # It uses the options set by the client to build an appropriate request.
         
     | 
| 
      
 9 
     | 
    
         
            +
                class RequestBuilder
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Initialize a new +RequestBuilder+ with the given SOAP operation.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # The operation may be specified using a symbol or a string.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(operation, options = {})
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @operation = operation
         
     | 
| 
      
 15 
     | 
    
         
            +
                    assign_options(options)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  # Writer for the <tt>HTTPI::Request</tt> object.
         
     | 
| 
      
 19 
     | 
    
         
            +
                  attr_writer :http
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Writer for the <tt>Savon::SOAP::XML</tt> object.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  attr_writer :soap
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  # Writer for the <tt>Akami::WSSE</tt> object.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  attr_writer :wsse
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  # Writer for the <tt>Wasabi::Document</tt> object.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  attr_writer :wsdl
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  # Writer for the <tt>Savon::Config</tt> object.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  attr_writer :config
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  # Writer for the attributes of the SOAP input tag. Accepts a Hash.
         
     | 
| 
      
 34 
     | 
    
         
            +
                  attr_writer :attributes
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  # Writer for the namespace identifer of the <tt>Savon::SOAP::XML</tt>
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # object.
         
     | 
| 
      
 38 
     | 
    
         
            +
                  attr_writer :namespace_identifier
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Writer for the SOAP action of the <tt>Savon::SOAP::XML</tt> object.
         
     | 
| 
      
 41 
     | 
    
         
            +
                  attr_writer :soap_action
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  # Reader for the operation of the request being built by the request builder.
         
     | 
| 
      
 44 
     | 
    
         
            +
                  attr_reader :operation
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  # Builds and returns a <tt>Savon::SOAP::Request</tt> object. You may optionally
         
     | 
| 
      
 47 
     | 
    
         
            +
                  # pass a block to the method that will be run after the initial configuration of
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # the dependencies. +self+ will be yielded to the block if the block accepts an
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # argument.
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def request(&post_configuration_block)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    configure_dependencies
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    if post_configuration_block
         
     | 
| 
      
 54 
     | 
    
         
            +
                      # Only yield self to the block if our block takes an argument
         
     | 
| 
      
 55 
     | 
    
         
            +
                      args = [] and (args << self if post_configuration_block.arity == 1)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      post_configuration_block.call(*args)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    Request.new(config, http, soap)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  # Returns the identifier for the default namespace. If an operation namespace
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # identifier is defined for the current operation in the WSDL document, this
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # namespace identifier is used. Otherwise, the +@namespace_identifier+ instance
         
     | 
| 
      
 65 
     | 
    
         
            +
                  # variable is used.
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def namespace_identifier
         
     | 
| 
      
 67 
     | 
    
         
            +
                    if operation_namespace_defined_in_wsdl?
         
     | 
| 
      
 68 
     | 
    
         
            +
                      wsdl.operations[operation][:namespace_identifier].to_sym
         
     | 
| 
      
 69 
     | 
    
         
            +
                    else
         
     | 
| 
      
 70 
     | 
    
         
            +
                      @namespace_identifier
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  # Returns the namespace identifier to be used for the the SOAP input tag.
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # If +@namespace_identifier+ is not +nil+, it will be returned. Otherwise, the
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # default namespace identifier as returned by +namespace_identifier+ will be
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # returned.
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def input_namespace_identifier
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @namespace_identifier || namespace_identifier
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  # Returns the default namespace to be used for the SOAP request. If a namespace
         
     | 
| 
      
 83 
     | 
    
         
            +
                  # is defined for the operation in the WSDL document, this namespace will be
         
     | 
| 
      
 84 
     | 
    
         
            +
                  # returned. Otherwise, the default WSDL document namespace will be returned.
         
     | 
| 
      
 85 
     | 
    
         
            +
                  def namespace
         
     | 
| 
      
 86 
     | 
    
         
            +
                    if operation_namespace_defined_in_wsdl?
         
     | 
| 
      
 87 
     | 
    
         
            +
                      wsdl.parser.namespaces[namespace_identifier.to_s]
         
     | 
| 
      
 88 
     | 
    
         
            +
                    else
         
     | 
| 
      
 89 
     | 
    
         
            +
                      wsdl.namespace
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  # Returns true if the operation's namespace is defined within the WSDL
         
     | 
| 
      
 94 
     | 
    
         
            +
                  # document.
         
     | 
| 
      
 95 
     | 
    
         
            +
                  def operation_namespace_defined_in_wsdl?
         
     | 
| 
      
 96 
     | 
    
         
            +
                    return false unless wsdl.document?
         
     | 
| 
      
 97 
     | 
    
         
            +
                    (operation = wsdl.operations[self.operation]) && operation[:namespace_identifier]
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  # Returns the SOAP action. If +@soap_action+ has been defined, this will
         
     | 
| 
      
 101 
     | 
    
         
            +
                  # be returned. Otherwise, if there is a WSDL document defined, the SOAP
         
     | 
| 
      
 102 
     | 
    
         
            +
                  # action corresponding to the operation will be returned. Failing this,
         
     | 
| 
      
 103 
     | 
    
         
            +
                  # the operation name will be used to form the SOAP action.
         
     | 
| 
      
 104 
     | 
    
         
            +
                  def soap_action
         
     | 
| 
      
 105 
     | 
    
         
            +
                    return @soap_action if @soap_action
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                    if wsdl.document?
         
     | 
| 
      
 108 
     | 
    
         
            +
                      wsdl.soap_action(operation.to_sym)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    else
         
     | 
| 
      
 110 
     | 
    
         
            +
                      Gyoku::XMLKey.create(operation).to_sym
         
     | 
| 
      
 111 
     | 
    
         
            +
                    end
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  # Returns the SOAP operation input tag. If there is a WSDL document defined,
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # and the operation's input tag is defined in the document, this will be
         
     | 
| 
      
 116 
     | 
    
         
            +
                  # returned. Otherwise, the operation name will be used to form the input tag.
         
     | 
| 
      
 117 
     | 
    
         
            +
                  def soap_input_tag
         
     | 
| 
      
 118 
     | 
    
         
            +
                    if wsdl.document? && (input = wsdl.soap_input(operation.to_sym))
         
     | 
| 
      
 119 
     | 
    
         
            +
                      input
         
     | 
| 
      
 120 
     | 
    
         
            +
                    else
         
     | 
| 
      
 121 
     | 
    
         
            +
                      Gyoku::XMLKey.create(operation)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  # Changes the body of the SOAP request to +body+.
         
     | 
| 
      
 126 
     | 
    
         
            +
                  def body=(body)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    soap.body = body
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  # Returns the body of the SOAP request.
         
     | 
| 
      
 131 
     | 
    
         
            +
                  def body
         
     | 
| 
      
 132 
     | 
    
         
            +
                    soap.body
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  # Returns the attributes of the SOAP input tag. Defaults to
         
     | 
| 
      
 136 
     | 
    
         
            +
                  # an empty Hash.
         
     | 
| 
      
 137 
     | 
    
         
            +
                  def attributes
         
     | 
| 
      
 138 
     | 
    
         
            +
                    @attributes ||= {}
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  # Returns the <tt>Savon::Config</tt> object for the request. Defaults
         
     | 
| 
      
 142 
     | 
    
         
            +
                  # to a clone of <tt>Savon.config</tt>.
         
     | 
| 
      
 143 
     | 
    
         
            +
                  def config
         
     | 
| 
      
 144 
     | 
    
         
            +
                    @config ||= Savon.config.clone
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  # Returns the <tt>HTTPI::Request</tt> object.
         
     | 
| 
      
 148 
     | 
    
         
            +
                  def http
         
     | 
| 
      
 149 
     | 
    
         
            +
                    @http ||= HTTPI::Request.new
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  # Returns the <tt>SOAP::XML</tt> object.
         
     | 
| 
      
 153 
     | 
    
         
            +
                  def soap
         
     | 
| 
      
 154 
     | 
    
         
            +
                    @soap ||= XML.new(config)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  # Returns the <tt>Wasabi::Document</tt> object.
         
     | 
| 
      
 158 
     | 
    
         
            +
                  def wsdl
         
     | 
| 
      
 159 
     | 
    
         
            +
                    @wsdl ||= Wasabi::Document.new
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                  # Returns the <tt>Akami::WSSE</tt> object.
         
     | 
| 
      
 163 
     | 
    
         
            +
                  def wsse
         
     | 
| 
      
 164 
     | 
    
         
            +
                    @wsse ||= Akami.wsse
         
     | 
| 
      
 165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  private
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                  def configure_dependencies
         
     | 
| 
      
 170 
     | 
    
         
            +
                    soap.endpoint = wsdl.endpoint
         
     | 
| 
      
 171 
     | 
    
         
            +
                    soap.element_form_default = wsdl.element_form_default
         
     | 
| 
      
 172 
     | 
    
         
            +
                    soap.wsse = wsse
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                    soap.namespace = namespace
         
     | 
| 
      
 175 
     | 
    
         
            +
                    soap.namespace_identifier = namespace_identifier
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                    add_wsdl_namespaces_to_soap
         
     | 
| 
      
 178 
     | 
    
         
            +
                    add_wsdl_types_to_soap
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                    soap.input = [input_namespace_identifier, soap_input_tag.to_sym, attributes]
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                    http.headers["SOAPAction"] = %{"#{soap_action}"}
         
     | 
| 
      
 183 
     | 
    
         
            +
                  end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                  def add_wsdl_namespaces_to_soap
         
     | 
| 
      
 186 
     | 
    
         
            +
                    wsdl.type_namespaces.each do |path, uri|
         
     | 
| 
      
 187 
     | 
    
         
            +
                      soap.use_namespace(path, uri)
         
     | 
| 
      
 188 
     | 
    
         
            +
                    end
         
     | 
| 
      
 189 
     | 
    
         
            +
                  end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                  def add_wsdl_types_to_soap
         
     | 
| 
      
 192 
     | 
    
         
            +
                    wsdl.type_definitions.each do |path, type|
         
     | 
| 
      
 193 
     | 
    
         
            +
                      soap.types[path] = type
         
     | 
| 
      
 194 
     | 
    
         
            +
                    end
         
     | 
| 
      
 195 
     | 
    
         
            +
                  end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                  def assign_options(options)
         
     | 
| 
      
 198 
     | 
    
         
            +
                    options.each do |option, value|
         
     | 
| 
      
 199 
     | 
    
         
            +
                      send(:"#{option}=", value) if value
         
     | 
| 
      
 200 
     | 
    
         
            +
                    end
         
     | 
| 
      
 201 
     | 
    
         
            +
                  end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
              end
         
     | 
| 
      
 205 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/savon/soap/xml.rb
    CHANGED
    
    | 
         @@ -220,7 +220,7 @@ module Savon 
     | 
|
| 
       220 
220 
     | 
    
         | 
| 
       221 
221 
     | 
    
         
             
                  def add_namespaces_to_body(hash, path = [input[1].to_s])
         
     | 
| 
       222 
222 
     | 
    
         
             
                    return unless hash
         
     | 
| 
       223 
     | 
    
         
            -
                    return hash if hash.kind_of?(Array)
         
     | 
| 
      
 223 
     | 
    
         
            +
                    return hash.map { |value| add_namespaces_to_body(value, path) } if hash.kind_of?(Array)
         
     | 
| 
       224 
224 
     | 
    
         
             
                    return hash.to_s unless hash.kind_of? Hash
         
     | 
| 
       225 
225 
     | 
    
         | 
| 
       226 
226 
     | 
    
         
             
                    hash.inject({}) do |newhash, (key, value)|
         
     | 
    
        data/lib/savon/version.rb
    CHANGED
    
    
| 
         @@ -19,8 +19,20 @@ 
     | 
|
| 
       19 
19 
     | 
    
         
             
                                </s:sequence>
         
     | 
| 
       20 
20 
     | 
    
         
             
                            </s:complexType>
         
     | 
| 
       21 
21 
     | 
    
         
             
                        </s:element>
         
     | 
| 
      
 22 
     | 
    
         
            +
                        <s:element name="Lookup">
         
     | 
| 
      
 23 
     | 
    
         
            +
                          <s:complexType>
         
     | 
| 
      
 24 
     | 
    
         
            +
                            <s:sequence>
         
     | 
| 
      
 25 
     | 
    
         
            +
                              <s:element minOccurs="0" maxOccurs="1" name="articles" type="article:ArrayOfArticle" />
         
     | 
| 
      
 26 
     | 
    
         
            +
                            </s:sequence>
         
     | 
| 
      
 27 
     | 
    
         
            +
                          </s:complexType>
         
     | 
| 
      
 28 
     | 
    
         
            +
                        </s:element>
         
     | 
| 
       22 
29 
     | 
    
         
             
                    </s:schema>
         
     | 
| 
       23 
30 
     | 
    
         
             
                    <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/article">
         
     | 
| 
      
 31 
     | 
    
         
            +
                        <s:complexType name="ArrayOfArticle">
         
     | 
| 
      
 32 
     | 
    
         
            +
                          <s:sequence>
         
     | 
| 
      
 33 
     | 
    
         
            +
                            <s:element minOccurs="0" maxOccurs="unbounded" name="Article" type="article:Article"/>
         
     | 
| 
      
 34 
     | 
    
         
            +
                          </s:sequence>
         
     | 
| 
      
 35 
     | 
    
         
            +
                        </s:complexType>
         
     | 
| 
       24 
36 
     | 
    
         
             
                        <s:complexType name="Article">
         
     | 
| 
       25 
37 
     | 
    
         
             
                            <s:sequence>
         
     | 
| 
       26 
38 
     | 
    
         
             
                                <s:element minOccurs="0" name="Author" type="s:string"/>
         
     | 
| 
         @@ -35,11 +47,21 @@ 
     | 
|
| 
       35 
47 
     | 
    
         
             
                <message name="SaveSoapOut">
         
     | 
| 
       36 
48 
     | 
    
         
             
                    <part name="parameters" element="actions:SaveResponse"/>
         
     | 
| 
       37 
49 
     | 
    
         
             
                </message>
         
     | 
| 
      
 50 
     | 
    
         
            +
                <message name="LookupSoapIn">
         
     | 
| 
      
 51 
     | 
    
         
            +
                    <part name="parameters" element="actions:Lookup"/>
         
     | 
| 
      
 52 
     | 
    
         
            +
                </message>
         
     | 
| 
      
 53 
     | 
    
         
            +
                <message name="LookupSoapOut">
         
     | 
| 
      
 54 
     | 
    
         
            +
                    <part name="parameters" element="actions:LookupResponse"/>
         
     | 
| 
      
 55 
     | 
    
         
            +
                </message>
         
     | 
| 
       38 
56 
     | 
    
         
             
                <portType name="ArticleSoap">
         
     | 
| 
       39 
57 
     | 
    
         
             
                    <operation name="Save">
         
     | 
| 
       40 
58 
     | 
    
         
             
                        <input message="actions:SaveSoapIn"/>
         
     | 
| 
       41 
59 
     | 
    
         
             
                        <output message="actions:SaveSoapOut"/>
         
     | 
| 
       42 
60 
     | 
    
         
             
                    </operation>
         
     | 
| 
      
 61 
     | 
    
         
            +
                    <operation name="Lookup">
         
     | 
| 
      
 62 
     | 
    
         
            +
                        <input message="actions:LookupSoapIn"/>
         
     | 
| 
      
 63 
     | 
    
         
            +
                        <input message="actions:LookupSoapOut"/>
         
     | 
| 
      
 64 
     | 
    
         
            +
                    </operation>
         
     | 
| 
       43 
65 
     | 
    
         
             
                </portType>
         
     | 
| 
       44 
66 
     | 
    
         
             
                <binding name="ArticleSoap" type="actions:ArticleSoap">
         
     | 
| 
       45 
67 
     | 
    
         
             
                    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
         
     | 
| 
         @@ -52,6 +74,15 @@ 
     | 
|
| 
       52 
74 
     | 
    
         
             
                            <soap:body use="literal"/>
         
     | 
| 
       53 
75 
     | 
    
         
             
                        </output>
         
     | 
| 
       54 
76 
     | 
    
         
             
                    </operation>
         
     | 
| 
      
 77 
     | 
    
         
            +
                    <operation name="Lookup">
         
     | 
| 
      
 78 
     | 
    
         
            +
                        <soap:operation soapAction="http://example.com/actions.Lookup" style="document"/>
         
     | 
| 
      
 79 
     | 
    
         
            +
                        <input>
         
     | 
| 
      
 80 
     | 
    
         
            +
                            <soap:body use="literal"/>
         
     | 
| 
      
 81 
     | 
    
         
            +
                        </input>
         
     | 
| 
      
 82 
     | 
    
         
            +
                        <output>
         
     | 
| 
      
 83 
     | 
    
         
            +
                            <soap:body use="literal"/>
         
     | 
| 
      
 84 
     | 
    
         
            +
                        </output>
         
     | 
| 
      
 85 
     | 
    
         
            +
                    </operation>
         
     | 
| 
       55 
86 
     | 
    
         
             
                </binding>
         
     | 
| 
       56 
87 
     | 
    
         
             
                <service name="StudyMDL">
         
     | 
| 
       57 
88 
     | 
    
         
             
                    <port name="StudyMDLSoap" binding="actions:StudyMDLSoap">
         
     | 
| 
         @@ -2,21 +2,60 @@ require "spec_helper" 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            describe "Integration" do
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
       6 
     | 
    
         
            -
                client = Savon.client( 
     | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
      
 5 
     | 
    
         
            +
              subject(:client) {
         
     | 
| 
      
 6 
     | 
    
         
            +
                client = Savon.client(service_endpoint)
         
     | 
| 
      
 7 
     | 
    
         
            +
                client.http.open_timeout = 10
         
     | 
| 
      
 8 
     | 
    
         
            +
                client.http.read_timeout = 10
         
     | 
| 
      
 9 
     | 
    
         
            +
                client
         
     | 
| 
      
 10 
     | 
    
         
            +
              }
         
     | 
| 
       8 
11 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
              context "stockquote" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                let(:service_endpoint) { "http://www.webservicex.net/stockquote.asmx?WSDL" }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                it "returns the result in a CDATA tag" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  response = client.request(:get_quote, :body => { :symbol => "AAPL" })
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  cdata = response[:get_quote_response][:get_quote_result]
         
     | 
| 
      
 19 
     | 
    
         
            +
                  result = Nori.parse(cdata)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  result[:stock_quotes][:stock][:symbol].should == "AAPL"
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              context "email" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                let(:service_endpoint) { "http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx?wsdl" }
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                it "passes Strings as they are" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  response = client.request(:verify_email, :body => { :email => "soap@example.com", "LicenseKey" => "?" })
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  response_text = response[:verify_email_response][:verify_email_result][:response_text]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  response_text.should == "Email Domain Not Found"
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
       12 
33 
     | 
    
         
             
              end
         
     | 
| 
       13 
34 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
               
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
              context "zip code" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                let(:service_endpoint) { "http://www.thomas-bayer.com/axis2/services/BLZService?wsdl" }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                it "supports threads making requests simultaneously" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                  mutex = Mutex.new
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  request_data = [70070010, 24050110, 20050550]
         
     | 
| 
      
 42 
     | 
    
         
            +
                  threads_waiting = request_data.size
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  threads = request_data.map do |blz|
         
     | 
| 
      
 45 
     | 
    
         
            +
                    Thread.new do
         
     | 
| 
      
 46 
     | 
    
         
            +
                      response = client.request :get_bank, :body => { :blz => blz }
         
     | 
| 
      
 47 
     | 
    
         
            +
                      Thread.current[:value] = response[:get_bank_response][:details]
         
     | 
| 
      
 48 
     | 
    
         
            +
                      mutex.synchronize { threads_waiting -= 1 }
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  sleep(1) until threads_waiting == 0
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  threads.each &:kill
         
     | 
| 
      
 55 
     | 
    
         
            +
                  values = threads.map { |thr| thr[:value] }.compact
         
     | 
| 
       17 
56 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                 
     | 
| 
      
 57 
     | 
    
         
            +
                  values.uniq.size.should == values.size
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
       20 
59 
     | 
    
         
             
              end
         
     | 
| 
       21 
60 
     | 
    
         | 
| 
       22 
61 
     | 
    
         
             
            end
         
     | 
    
        data/spec/savon/client_spec.rb
    CHANGED
    
    | 
         @@ -14,14 +14,14 @@ describe Savon::Client do 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                context "with a block expecting one argument" do
         
     | 
| 
       16 
16 
     | 
    
         
             
                  it "should yield the WSDL object" do
         
     | 
| 
       17 
     | 
    
         
            -
                    Savon::Client.new { |wsdl| wsdl.should be_a( 
     | 
| 
      
 17 
     | 
    
         
            +
                    Savon::Client.new { |wsdl| wsdl.should be_a(Wasabi::Document) }
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         
             
                end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                context "with a block expecting two arguments" do
         
     | 
| 
       22 
22 
     | 
    
         
             
                  it "should yield the WSDL and HTTP objects" do
         
     | 
| 
       23 
23 
     | 
    
         
             
                    Savon::Client.new do |wsdl, http|
         
     | 
| 
       24 
     | 
    
         
            -
                      wsdl.should be_an( 
     | 
| 
      
 24 
     | 
    
         
            +
                      wsdl.should be_an(Wasabi::Document)
         
     | 
| 
       25 
25 
     | 
    
         
             
                      http.should be_an(HTTPI::Request)
         
     | 
| 
       26 
26 
     | 
    
         
             
                    end
         
     | 
| 
       27 
27 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -30,7 +30,7 @@ describe Savon::Client do 
     | 
|
| 
       30 
30 
     | 
    
         
             
                context "with a block expecting three arguments" do
         
     | 
| 
       31 
31 
     | 
    
         
             
                  it "should yield the WSDL, HTTP and WSSE objects" do
         
     | 
| 
       32 
32 
     | 
    
         
             
                    Savon::Client.new do |wsdl, http, wsse|
         
     | 
| 
       33 
     | 
    
         
            -
                      wsdl.should be_an( 
     | 
| 
      
 33 
     | 
    
         
            +
                      wsdl.should be_an(Wasabi::Document)
         
     | 
| 
       34 
34 
     | 
    
         
             
                      http.should be_an(HTTPI::Request)
         
     | 
| 
       35 
35 
     | 
    
         
             
                      wsse.should be_an(Akami::WSSE)
         
     | 
| 
       36 
36 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -39,7 +39,7 @@ describe Savon::Client do 
     | 
|
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                context "with a block expecting no arguments" do
         
     | 
| 
       41 
41 
     | 
    
         
             
                  it "should let you access the WSDL object" do
         
     | 
| 
       42 
     | 
    
         
            -
                    Savon::Client.new { wsdl.should be_a( 
     | 
| 
      
 42 
     | 
    
         
            +
                    Savon::Client.new { wsdl.should be_a(Wasabi::Document) }
         
     | 
| 
       43 
43 
     | 
    
         
             
                  end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                  it "should let you access the HTTP object" do
         
     | 
| 
         @@ -54,7 +54,7 @@ describe Savon::Client do 
     | 
|
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
              describe "#wsdl" do
         
     | 
| 
       56 
56 
     | 
    
         
             
                it "should return the Savon::Wasabi::Document" do
         
     | 
| 
       57 
     | 
    
         
            -
                  client.wsdl.should be_a( 
     | 
| 
      
 57 
     | 
    
         
            +
                  client.wsdl.should be_a(Wasabi::Document)
         
     | 
| 
       58 
58 
     | 
    
         
             
                end
         
     | 
| 
       59 
59 
     | 
    
         
             
              end
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
         @@ -71,9 +71,16 @@ describe Savon::Client do 
     | 
|
| 
       71 
71 
     | 
    
         
             
              end
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
       73 
73 
     | 
    
         
             
              describe "#request" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                let(:request_builder) { stub_everything('request_builder') }
         
     | 
| 
      
 75 
     | 
    
         
            +
                let(:response) { mock('response') }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       74 
77 
     | 
    
         
             
                before do
         
     | 
| 
       75 
78 
     | 
    
         
             
                  HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:authentication)))
         
     | 
| 
       76 
79 
     | 
    
         
             
                  HTTPI.stubs(:post).returns(new_response)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  Savon::SOAP::RequestBuilder.stubs(:new).returns(request_builder)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  request_builder.stubs(:request).returns(stub(:response => response))
         
     | 
| 
      
 83 
     | 
    
         
            +
                  response.stubs(:http).returns(new_response)
         
     | 
| 
       77 
84 
     | 
    
         
             
                end
         
     | 
| 
       78 
85 
     | 
    
         | 
| 
       79 
86 
     | 
    
         
             
                context "without any arguments" do
         
     | 
| 
         @@ -82,73 +89,61 @@ describe Savon::Client do 
     | 
|
| 
       82 
89 
     | 
    
         
             
                  end
         
     | 
| 
       83 
90 
     | 
    
         
             
                end
         
     | 
| 
       84 
91 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                 
     | 
| 
       86 
     | 
    
         
            -
                  it " 
     | 
| 
       87 
     | 
    
         
            -
                     
     | 
| 
      
 92 
     | 
    
         
            +
                describe "setting dependencies of the request builder" do
         
     | 
| 
      
 93 
     | 
    
         
            +
                  it "sets the wsdl property with the client's WSDL document" do
         
     | 
| 
      
 94 
     | 
    
         
            +
                    request_builder.expects(:wsdl=).with(client.wsdl)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    client.request(:get_user)
         
     | 
| 
       88 
96 
     | 
    
         
             
                  end
         
     | 
| 
       89 
97 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                  it " 
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
       92 
     | 
    
         
            -
                     
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                    client.request :get_user
         
     | 
| 
      
 98 
     | 
    
         
            +
                  it "sets the http property with an HTTPI::Request object" do
         
     | 
| 
      
 99 
     | 
    
         
            +
                    request_builder.expects(:http=).with { |http| http.is_a?(HTTPI::Request) }
         
     | 
| 
      
 100 
     | 
    
         
            +
                    client.request(:get_user)
         
     | 
| 
       95 
101 
     | 
    
         
             
                  end
         
     | 
| 
       96 
102 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
                  it " 
     | 
| 
       98 
     | 
    
         
            -
                     
     | 
| 
       99 
     | 
    
         
            -
                     
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                    client.request(:get_user) { soap.namespace = nil }
         
     | 
| 
      
 103 
     | 
    
         
            +
                  it "sets the wsse property with an Akami:WSSE object" do
         
     | 
| 
      
 104 
     | 
    
         
            +
                    request_builder.expects(:wsse=).with { |wsse| wsse.is_a?(Akami::WSSE) }
         
     | 
| 
      
 105 
     | 
    
         
            +
                    client.request(:get_user)
         
     | 
| 
       102 
106 
     | 
    
         
             
                  end
         
     | 
| 
       103 
107 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
                   
     | 
| 
       105 
     | 
    
         
            -
                     
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
                    end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    it "sets the soap's namespace identifier to the matching operation's namespace identifier" do
         
     | 
| 
       110 
     | 
    
         
            -
                      client.request(:authenticate) { soap.namespace_identifier.should == :tns }
         
     | 
| 
       111 
     | 
    
         
            -
                    end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                    it "sets the soap's namespace to the namspace matching the identifier" do
         
     | 
| 
       114 
     | 
    
         
            -
                      client.request(:authenticate) { soap.namespace.should == "http://v1_0.ws.auth.order.example.com/" }
         
     | 
| 
       115 
     | 
    
         
            -
                    end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                    it "sets the input tag to result in <tns:authenticate>" do
         
     | 
| 
       118 
     | 
    
         
            -
                      client.request(:authenticate) { soap.input.should == [:tns, :authenticate, {}] }
         
     | 
| 
       119 
     | 
    
         
            -
                    end
         
     | 
| 
      
 108 
     | 
    
         
            +
                  it "sets the config property with a Savon::Config object" do
         
     | 
| 
      
 109 
     | 
    
         
            +
                    request_builder.expects(:config=).with { |config| config.is_a?(Savon::Config) }
         
     | 
| 
      
 110 
     | 
    
         
            +
                    client.request(:get_user)
         
     | 
| 
       120 
111 
     | 
    
         
             
                  end
         
     | 
| 
       121 
112 
     | 
    
         
             
                end
         
     | 
| 
       122 
113 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                context "with a single argument 
     | 
| 
       124 
     | 
    
         
            -
                  it " 
     | 
| 
       125 
     | 
    
         
            -
                     
     | 
| 
      
 114 
     | 
    
         
            +
                context "with a single argument" do
         
     | 
| 
      
 115 
     | 
    
         
            +
                  it "sets the operation of the request builder to the argument" do
         
     | 
| 
      
 116 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    client.request(:get_user)
         
     | 
| 
       126 
118 
     | 
    
         
             
                  end
         
     | 
| 
       127 
119 
     | 
    
         
             
                end
         
     | 
| 
       128 
120 
     | 
    
         | 
| 
       129 
121 
     | 
    
         
             
                context "with a Symbol and a Hash" do
         
     | 
| 
       130 
     | 
    
         
            -
                  it " 
     | 
| 
       131 
     | 
    
         
            -
                     
     | 
| 
      
 122 
     | 
    
         
            +
                  it "uses the hash to set attributes of the request builder" do
         
     | 
| 
      
 123 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :attributes => { :active => true })
         
     | 
| 
      
 124 
     | 
    
         
            +
                    client.request(:get_user, :active => true)
         
     | 
| 
       132 
125 
     | 
    
         
             
                  end
         
     | 
| 
       133 
126 
     | 
    
         | 
| 
       134 
     | 
    
         
            -
                  it " 
     | 
| 
       135 
     | 
    
         
            -
                     
     | 
| 
      
 127 
     | 
    
         
            +
                  it "uses the :soap_action key of the hash to set the SOAP action of the request builder" do
         
     | 
| 
      
 128 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :soap_action => :test_action)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    client.request(:get_user, :soap_action => :test_action)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  it "uses the :body key of the hash to set the SOAP body of the request builder" do
         
     | 
| 
      
 133 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :body => { :foo => "bar" })
         
     | 
| 
      
 134 
     | 
    
         
            +
                    client.request(:get_user, :body => { :foo => "bar" })
         
     | 
| 
       136 
135 
     | 
    
         
             
                  end
         
     | 
| 
       137 
136 
     | 
    
         
             
                end
         
     | 
| 
       138 
137 
     | 
    
         | 
| 
       139 
138 
     | 
    
         
             
                context "with two Symbols" do
         
     | 
| 
       140 
     | 
    
         
            -
                  it " 
     | 
| 
       141 
     | 
    
         
            -
                     
     | 
| 
      
 139 
     | 
    
         
            +
                  it "uses the first symbol to set the namespace and the second symbol to set the operation of the request builder" do
         
     | 
| 
      
 140 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :namespace_identifier => :v1)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    client.request(:v1, :get_user)
         
     | 
| 
       142 
142 
     | 
    
         
             
                  end
         
     | 
| 
       143 
143 
     | 
    
         | 
| 
       144 
     | 
    
         
            -
                  it "should set the target namespace  
     | 
| 
       145 
     | 
    
         
            -
                     
     | 
| 
       146 
     | 
    
         
            -
                    HTTPI::Request.any_instance.expects(:body=).with { |value| value.include? namespace }
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
                    client.request :v1, :get_user
         
     | 
| 
       149 
     | 
    
         
            -
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  it "should not set the target namespace if soap.namespace was set to nil in the post-configuration block" do
         
     | 
| 
      
 145 
     | 
    
         
            +
                    Savon::SOAP::RequestBuilder.unstub(:new)
         
     | 
| 
       150 
146 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
                  it "should not set the target namespace if soap.namespace was set to nil" do
         
     | 
| 
       152 
147 
     | 
    
         
             
                    namespace = 'xmlns:v1="http://v1_0.ws.auth.order.example.com/"'
         
     | 
| 
       153 
148 
     | 
    
         
             
                    HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
         
     | 
| 
       154 
149 
     | 
    
         | 
| 
         @@ -157,66 +152,118 @@ describe Savon::Client do 
     | 
|
| 
       157 
152 
     | 
    
         
             
                end
         
     | 
| 
       158 
153 
     | 
    
         | 
| 
       159 
154 
     | 
    
         
             
                context "with two Symbols and a Hash" do
         
     | 
| 
       160 
     | 
    
         
            -
                  it " 
     | 
| 
       161 
     | 
    
         
            -
                     
     | 
| 
      
 155 
     | 
    
         
            +
                  it "uses the first symbol to set the namespace and the second symbol to set the operation of the request builder" do
         
     | 
| 
      
 156 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :namespace_identifier => :wsdl)
         
     | 
| 
      
 157 
     | 
    
         
            +
                    client.request(:wsdl, :get_user)
         
     | 
| 
       162 
158 
     | 
    
         
             
                  end
         
     | 
| 
       163 
159 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                  it "should use the  
     | 
| 
       165 
     | 
    
         
            -
                     
     | 
| 
      
 160 
     | 
    
         
            +
                  it "should use the hash to set the attributes of the request builder" do
         
     | 
| 
      
 161 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :namespace_identifier => :wsdl, :attributes => { :active => true })
         
     | 
| 
      
 162 
     | 
    
         
            +
                    client.request(:wsdl, :get_user, :active => true)
         
     | 
| 
       166 
163 
     | 
    
         
             
                  end
         
     | 
| 
       167 
     | 
    
         
            -
                end
         
     | 
| 
       168 
164 
     | 
    
         | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
                    client.request(: 
     | 
| 
      
 165 
     | 
    
         
            +
                  it "should use the :soap_action key of the hash to set the SOAP action of the request builder" do
         
     | 
| 
      
 166 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :namespace_identifier => :wsdl, :soap_action => :test_action)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    client.request(:wsdl, :get_user, :soap_action => :test_action)
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                  it "should use the :body key of the hash to set the SOAP body of the request builder" do
         
     | 
| 
      
 171 
     | 
    
         
            +
                    expect_request_builder_to_receive(:get_user, :namespace_identifier => :wsdl, :body => { :foo => "bar" })
         
     | 
| 
      
 172 
     | 
    
         
            +
                    client.request(:wsdl, :get_user, :body => { :foo => "bar" })
         
     | 
| 
       172 
173 
     | 
    
         
             
                  end
         
     | 
| 
       173 
174 
     | 
    
         
             
                end
         
     | 
| 
       174 
175 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
                context "with a block 
     | 
| 
       176 
     | 
    
         
            -
                   
     | 
| 
       177 
     | 
    
         
            -
                     
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
      
 176 
     | 
    
         
            +
                context "with a block" do
         
     | 
| 
      
 177 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 178 
     | 
    
         
            +
                    Savon::SOAP::RequestBuilder.unstub(:new)
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                  it "passes the block to the request builder" do
         
     | 
| 
      
 182 
     | 
    
         
            +
                    # this is painful. it would be trivial to test in > Ruby 1.9, but this is
         
     | 
| 
      
 183 
     | 
    
         
            +
                    # the only way I know how in < 1.9.
         
     | 
| 
      
 184 
     | 
    
         
            +
                    dummy = Object.new
         
     | 
| 
      
 185 
     | 
    
         
            +
                    dummy.instance_eval do
         
     | 
| 
      
 186 
     | 
    
         
            +
                      class << self; attr_accessor :request_builder, :block_given; end
         
     | 
| 
      
 187 
     | 
    
         
            +
                      def request
         
     | 
| 
      
 188 
     | 
    
         
            +
                        self.block_given = block_given?
         
     | 
| 
      
 189 
     | 
    
         
            +
                        request_builder.request
         
     | 
| 
      
 190 
     | 
    
         
            +
                      end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                      def method_missing(_, *args)
         
     | 
| 
      
 193 
     | 
    
         
            +
                      end
         
     | 
| 
       180 
194 
     | 
    
         
             
                    end
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                    dummy.request_builder = request_builder
         
     | 
| 
      
 197 
     | 
    
         
            +
                    Savon::SOAP::RequestBuilder.stubs(:new).returns(dummy)
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                    blk = lambda {}
         
     | 
| 
      
 200 
     | 
    
         
            +
                    client.request(:authenticate, &blk)
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                    dummy.block_given.should == true
         
     | 
| 
       181 
203 
     | 
    
         
             
                  end
         
     | 
| 
       182 
     | 
    
         
            -
                end
         
     | 
| 
       183 
204 
     | 
    
         | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                       
     | 
| 
       189 
     | 
    
         
            -
                      http.should be_an(HTTPI::Request)
         
     | 
| 
      
 205 
     | 
    
         
            +
                  it "executes the block in the context of the request builder" do
         
     | 
| 
      
 206 
     | 
    
         
            +
                    Savon::SOAP::RequestBuilder.class_eval do
         
     | 
| 
      
 207 
     | 
    
         
            +
                      def who
         
     | 
| 
      
 208 
     | 
    
         
            +
                        self
         
     | 
| 
      
 209 
     | 
    
         
            +
                      end
         
     | 
| 
       190 
210 
     | 
    
         
             
                    end
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                    client.request(:authenticate) { who.should be_a Savon::SOAP::RequestBuilder }
         
     | 
| 
       191 
213 
     | 
    
         
             
                  end
         
     | 
| 
       192 
     | 
    
         
            -
                end
         
     | 
| 
       193 
214 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
                      soap.should be_a(Savon::SOAP::XML)
         
     | 
| 
       198 
     | 
    
         
            -
                      wsdl.should be_a(Savon::Wasabi::Document)
         
     | 
| 
       199 
     | 
    
         
            -
                      http.should be_an(HTTPI::Request)
         
     | 
| 
       200 
     | 
    
         
            -
                      wsse.should be_a(Akami::WSSE)
         
     | 
| 
      
 215 
     | 
    
         
            +
                  context "with a block expecting one argument" do
         
     | 
| 
      
 216 
     | 
    
         
            +
                    it "should yield the SOAP object" do
         
     | 
| 
      
 217 
     | 
    
         
            +
                      client.request(:authenticate) { |soap| soap.should be_a Savon::SOAP::XML }
         
     | 
| 
       201 
218 
     | 
    
         
             
                    end
         
     | 
| 
       202 
219 
     | 
    
         
             
                  end
         
     | 
| 
       203 
     | 
    
         
            -
                end
         
     | 
| 
       204 
220 
     | 
    
         | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
      
 221 
     | 
    
         
            +
                  context "with a block expecting two arguments" do
         
     | 
| 
      
 222 
     | 
    
         
            +
                    it "should yield the SOAP and WSDL objects" do
         
     | 
| 
      
 223 
     | 
    
         
            +
                      client.request(:authenticate) do |soap, wsdl|
         
     | 
| 
      
 224 
     | 
    
         
            +
                        soap.should be_a(Savon::SOAP::XML)
         
     | 
| 
      
 225 
     | 
    
         
            +
                        wsdl.should be_an(Wasabi::Document)
         
     | 
| 
      
 226 
     | 
    
         
            +
                      end
         
     | 
| 
      
 227 
     | 
    
         
            +
                    end
         
     | 
| 
       208 
228 
     | 
    
         
             
                  end
         
     | 
| 
       209 
229 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
                   
     | 
| 
       211 
     | 
    
         
            -
                     
     | 
| 
      
 230 
     | 
    
         
            +
                  context "with a block expecting three arguments" do
         
     | 
| 
      
 231 
     | 
    
         
            +
                    it "should yield the SOAP, WSDL and HTTP objects" do
         
     | 
| 
      
 232 
     | 
    
         
            +
                      client.request(:authenticate) do |soap, wsdl, http|
         
     | 
| 
      
 233 
     | 
    
         
            +
                        soap.should be_a(Savon::SOAP::XML)
         
     | 
| 
      
 234 
     | 
    
         
            +
                        wsdl.should be_an(Wasabi::Document)
         
     | 
| 
      
 235 
     | 
    
         
            +
                        http.should be_an(HTTPI::Request)
         
     | 
| 
      
 236 
     | 
    
         
            +
                      end
         
     | 
| 
      
 237 
     | 
    
         
            +
                    end
         
     | 
| 
       212 
238 
     | 
    
         
             
                  end
         
     | 
| 
       213 
239 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
                   
     | 
| 
       215 
     | 
    
         
            -
                     
     | 
| 
      
 240 
     | 
    
         
            +
                  context "with a block expecting four arguments" do
         
     | 
| 
      
 241 
     | 
    
         
            +
                    it "should yield the SOAP, WSDL, HTTP and WSSE objects" do
         
     | 
| 
      
 242 
     | 
    
         
            +
                      client.request(:authenticate) do |soap, wsdl, http, wsse|
         
     | 
| 
      
 243 
     | 
    
         
            +
                        soap.should be_a(Savon::SOAP::XML)
         
     | 
| 
      
 244 
     | 
    
         
            +
                        wsdl.should be_a(Wasabi::Document)
         
     | 
| 
      
 245 
     | 
    
         
            +
                        http.should be_an(HTTPI::Request)
         
     | 
| 
      
 246 
     | 
    
         
            +
                        wsse.should be_a(Akami::WSSE)
         
     | 
| 
      
 247 
     | 
    
         
            +
                      end
         
     | 
| 
      
 248 
     | 
    
         
            +
                    end
         
     | 
| 
       216 
249 
     | 
    
         
             
                  end
         
     | 
| 
       217 
250 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
                   
     | 
| 
       219 
     | 
    
         
            -
                     
     | 
| 
      
 251 
     | 
    
         
            +
                  context "with a block expecting no arguments" do
         
     | 
| 
      
 252 
     | 
    
         
            +
                    it "should let you access the SOAP object" do
         
     | 
| 
      
 253 
     | 
    
         
            +
                      client.request(:authenticate) { soap.should be_a(Savon::SOAP::XML) }
         
     | 
| 
      
 254 
     | 
    
         
            +
                    end
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                    it "should let you access the HTTP object" do
         
     | 
| 
      
 257 
     | 
    
         
            +
                      client.request(:authenticate) { http.should be_an(HTTPI::Request) }
         
     | 
| 
      
 258 
     | 
    
         
            +
                    end
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
                    it "should let you access the WSSE object" do
         
     | 
| 
      
 261 
     | 
    
         
            +
                      client.request(:authenticate) { wsse.should be_a(Akami::WSSE) }
         
     | 
| 
      
 262 
     | 
    
         
            +
                    end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                    it "should let you access the WSDL object" do
         
     | 
| 
      
 265 
     | 
    
         
            +
                      client.request(:authenticate) { wsdl.should be_a(Wasabi::Document) }
         
     | 
| 
      
 266 
     | 
    
         
            +
                    end
         
     | 
| 
       220 
267 
     | 
    
         
             
                  end
         
     | 
| 
       221 
268 
     | 
    
         
             
                end
         
     | 
| 
       222 
269 
     | 
    
         | 
| 
         @@ -383,29 +430,55 @@ describe Savon::Client do 
     | 
|
| 
       383 
430 
     | 
    
         
             
              end
         
     | 
| 
       384 
431 
     | 
    
         | 
| 
       385 
432 
     | 
    
         
             
              context "with an Array of namespaced items" do
         
     | 
| 
       386 
     | 
    
         
            -
                 
     | 
| 
      
 433 
     | 
    
         
            +
                context "with a single namespace" do
         
     | 
| 
      
 434 
     | 
    
         
            +
                  let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/taxcloud.xml" } }
         
     | 
| 
       387 
435 
     | 
    
         | 
| 
       388 
     | 
    
         
            -
             
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
             
     | 
| 
      
 436 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 437 
     | 
    
         
            +
                    HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:taxcloud)))
         
     | 
| 
      
 438 
     | 
    
         
            +
                    HTTPI.stubs(:post).returns(new_response)
         
     | 
| 
      
 439 
     | 
    
         
            +
                  end
         
     | 
| 
      
 440 
     | 
    
         
            +
             
     | 
| 
      
 441 
     | 
    
         
            +
                  it "should namespaces each Array item as expected" do
         
     | 
| 
      
 442 
     | 
    
         
            +
                    HTTPI::Request.any_instance.expects(:body=).with do |value|
         
     | 
| 
      
 443 
     | 
    
         
            +
                      xml = Nokogiri::XML(value)
         
     | 
| 
      
 444 
     | 
    
         
            +
                      !!xml.at_xpath(".//tc:cartItems/tc:CartItem/tc:ItemID", { "tc" => "http://taxcloud.net" })
         
     | 
| 
      
 445 
     | 
    
         
            +
                    end
         
     | 
| 
      
 446 
     | 
    
         
            +
             
     | 
| 
      
 447 
     | 
    
         
            +
                    address = { "Address1" => "888 6th Ave", "Address2" => nil, "City" => "New York", "State" => "NY", "Zip5" => "10001", "Zip4" => nil }
         
     | 
| 
      
 448 
     | 
    
         
            +
                    cart_item = { "Index" => 0, "ItemID" => "SKU-TEST", "TIC" => "00000", "Price" => 50.0, "Qty" => 1 }
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
      
 450 
     | 
    
         
            +
                    client.request :lookup, :body => {
         
     | 
| 
      
 451 
     | 
    
         
            +
                      "customerID"  => 123,
         
     | 
| 
      
 452 
     | 
    
         
            +
                      "cartID"      => 456,
         
     | 
| 
      
 453 
     | 
    
         
            +
                      "cartItems"   => { "CartItem" => [cart_item] },
         
     | 
| 
      
 454 
     | 
    
         
            +
                      "origin"      => address,
         
     | 
| 
      
 455 
     | 
    
         
            +
                      "destination" => address
         
     | 
| 
      
 456 
     | 
    
         
            +
                    }
         
     | 
| 
      
 457 
     | 
    
         
            +
                  end
         
     | 
| 
       391 
458 
     | 
    
         
             
                end
         
     | 
| 
       392 
459 
     | 
    
         | 
| 
       393 
     | 
    
         
            -
                 
     | 
| 
       394 
     | 
    
         
            -
                   
     | 
| 
       395 
     | 
    
         
            -
             
     | 
| 
      
 460 
     | 
    
         
            +
                context "with multiple namespaces" do
         
     | 
| 
      
 461 
     | 
    
         
            +
                  let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/multiple_namespaces.xml" } }
         
     | 
| 
      
 462 
     | 
    
         
            +
             
     | 
| 
      
 463 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 464 
     | 
    
         
            +
                    HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:multiple_namespaces)))
         
     | 
| 
      
 465 
     | 
    
         
            +
                    HTTPI.stubs(:post).returns(new_response)
         
     | 
| 
       396 
466 
     | 
    
         
             
                  end
         
     | 
| 
       397 
467 
     | 
    
         | 
| 
       398 
     | 
    
         
            -
                   
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
      
 468 
     | 
    
         
            +
                  it "should namespace each Array item as expected" do
         
     | 
| 
      
 469 
     | 
    
         
            +
                    HTTPI::Request.any_instance.expects(:body=).with do |value|
         
     | 
| 
      
 470 
     | 
    
         
            +
                      xml = Nokogiri::XML(value)
         
     | 
| 
      
 471 
     | 
    
         
            +
                      namespaces = { "actions" => "http://example.com/actions", "article" => "http://example.com/article" }
         
     | 
| 
      
 472 
     | 
    
         
            +
                      !!xml.at_xpath(".//actions:Lookup/actions:articles/article:Article/article:Author", namespaces)
         
     | 
| 
      
 473 
     | 
    
         
            +
                    end
         
     | 
| 
       400 
474 
     | 
    
         | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
       402 
     | 
    
         
            -
                     
     | 
| 
       403 
     | 
    
         
            -
             
     | 
| 
       404 
     | 
    
         
            -
                     
     | 
| 
       405 
     | 
    
         
            -
             
     | 
| 
       406 
     | 
    
         
            -
                    "destination" => address
         
     | 
| 
       407 
     | 
    
         
            -
                  }
         
     | 
| 
      
 475 
     | 
    
         
            +
                    article = { "Author" => "John Smith", "Title" => "Modern SOAP" }
         
     | 
| 
      
 476 
     | 
    
         
            +
                    client.request :lookup, :body => {
         
     | 
| 
      
 477 
     | 
    
         
            +
                      "articles" => { "Article" => [article] }
         
     | 
| 
      
 478 
     | 
    
         
            +
                    }
         
     | 
| 
      
 479 
     | 
    
         
            +
                  end
         
     | 
| 
       408 
480 
     | 
    
         
             
                end
         
     | 
| 
      
 481 
     | 
    
         
            +
             
     | 
| 
       409 
482 
     | 
    
         
             
              end
         
     | 
| 
       410 
483 
     | 
    
         | 
| 
       411 
484 
     | 
    
         
             
              context "without a WSDL document" do
         
     | 
| 
         @@ -476,4 +549,8 @@ describe Savon::Client do 
     | 
|
| 
       476 
549 
     | 
    
         
             
                HTTPI::Response.new response[:code], response[:headers], response[:body]
         
     | 
| 
       477 
550 
     | 
    
         
             
              end
         
     | 
| 
       478 
551 
     | 
    
         | 
| 
      
 552 
     | 
    
         
            +
              def expect_request_builder_to_receive(operation, options = {})
         
     | 
| 
      
 553 
     | 
    
         
            +
                Savon::SOAP::RequestBuilder.expects(:new).with(operation, options).returns(request_builder)
         
     | 
| 
      
 554 
     | 
    
         
            +
              end
         
     | 
| 
      
 555 
     | 
    
         
            +
             
     | 
| 
       479 
556 
     | 
    
         
             
            end
         
     |