savon 2.2.0 → 2.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +20 -9
- data/CHANGELOG.md +157 -10
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +10 -2
- data/README.md +38 -13
- data/donate.png +0 -0
- data/lib/savon/builder.rb +81 -15
- data/lib/savon/client.rb +6 -2
- data/lib/savon/core_ext/string.rb +0 -1
- data/lib/savon/header.rb +68 -17
- data/lib/savon/log_message.rb +7 -3
- data/lib/savon/message.rb +6 -7
- data/lib/savon/mock/expectation.rb +12 -2
- data/lib/savon/model.rb +4 -0
- data/lib/savon/operation.rb +45 -38
- data/lib/savon/options.rb +149 -22
- data/lib/savon/qualified_message.rb +31 -25
- data/lib/savon/request.rb +24 -4
- data/lib/savon/request_logger.rb +48 -0
- data/lib/savon/response.rb +35 -18
- data/lib/savon/soap_fault.rb +11 -11
- data/lib/savon/version.rb +1 -3
- data/savon.gemspec +12 -11
- data/spec/fixtures/response/empty_soap_fault.xml +13 -0
- data/spec/fixtures/response/f5.xml +39 -0
- data/spec/fixtures/response/no_body.xml +1 -0
- data/spec/fixtures/response/soap_fault_funky.xml +8 -0
- data/spec/fixtures/wsdl/brand.xml +624 -0
- data/spec/fixtures/wsdl/elements_in_types.xml +43 -0
- data/spec/fixtures/wsdl/no_message_tag.xml +1267 -0
- data/spec/fixtures/wsdl/vies.xml +176 -0
- data/spec/integration/centra_spec.rb +67 -0
- data/spec/integration/email_example_spec.rb +1 -1
- data/spec/integration/random_quote_spec.rb +23 -0
- data/spec/integration/stockquote_example_spec.rb +7 -1
- data/spec/integration/support/application.rb +1 -1
- data/spec/integration/zipcode_example_spec.rb +1 -1
- data/spec/savon/builder_spec.rb +50 -0
- data/spec/savon/client_spec.rb +78 -0
- data/spec/savon/core_ext/string_spec.rb +9 -9
- data/spec/savon/features/message_tag_spec.rb +5 -0
- data/spec/savon/http_error_spec.rb +2 -2
- data/spec/savon/log_message_spec.rb +18 -1
- data/spec/savon/message_spec.rb +70 -0
- data/spec/savon/mock_spec.rb +31 -0
- data/spec/savon/model_spec.rb +28 -0
- data/spec/savon/operation_spec.rb +69 -3
- data/spec/savon/options_spec.rb +515 -87
- data/spec/savon/qualified_message_spec.rb +101 -0
- data/spec/savon/request_logger_spec.rb +37 -0
- data/spec/savon/request_spec.rb +85 -10
- data/spec/savon/response_spec.rb +118 -27
- data/spec/savon/soap_fault_spec.rb +25 -5
- data/spec/savon/softlayer_spec.rb +27 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/adapters.rb +48 -0
- data/spec/support/integration.rb +1 -1
- metadata +76 -93
@@ -0,0 +1,176 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<wsdl:definitions targetNamespace="urn:ec.europa.eu:taxud:vies:services:checkVat" xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:impl="urn:ec.europa.eu:taxud:vies:services:checkVat" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
|
3
|
+
<xsd:documentation>
|
4
|
+
Specific disclaimer for this service ----------------------------------------- The
|
5
|
+
objective of this Internet site is to allow persons involved in the intra-Community supply of
|
6
|
+
goods or of services to obtain confirmation of the validity of the VAT identification number of
|
7
|
+
any specified person, in accordance to article 27 of Council Regulation (EC) No. 1798/2003 of 7
|
8
|
+
October 2003. Any other use and any extraction and use of the data which is not in conformity
|
9
|
+
with the objective of this site is strictly forbidden. Any retransmission of the contents of
|
10
|
+
this site, whether for a commercial purpose or otherwise, as well as any more general use other
|
11
|
+
than as far as is necessary to support the activity of a legitimate user (for example: to draw
|
12
|
+
up their own invoices) is expressly forbidden. In addition, any copying or reproduction of the
|
13
|
+
contents of this site is strictly forbidden. The European Commission maintains this website to
|
14
|
+
enhance the access by taxable persons making intra-Community supplies to verification of their
|
15
|
+
customers VAT identification numbers. Our goal is to supply instantaneous and accurate
|
16
|
+
information. However the Commission accepts no responsibility or liability whatsoever with
|
17
|
+
regard to the information obtained using this site. This information: - is obtained from Member
|
18
|
+
States databases over which the Commission services have no control and for which the Commission
|
19
|
+
assumes no responsibility; it is the responsibility of the Member States to keep their databases
|
20
|
+
complete, accurate and up to date; - is not professional or legal advice (if you need specific
|
21
|
+
advice, you should always consult a suitably qualified professional); - does not in itself give
|
22
|
+
a right to exempt intra-Community supplies from Value Added Tax; - does not change any
|
23
|
+
obligations imposed on taxable persons in relation to intra-Community supplies. It is our goal
|
24
|
+
to minimise disruption caused by technical errors. However some data or information on our site
|
25
|
+
may have been created or structured in files or formats which are not error-free and we cannot
|
26
|
+
guarantee that our service will not be interrupted or otherwise affected by such problems. The
|
27
|
+
Commission accepts no responsibility with regard to such problems incurred as a result of using
|
28
|
+
this site or any linked external sites. This disclaimer is not intended to limit the liability
|
29
|
+
of the Commission in contravention of any requirements laid down in applicable national law nor
|
30
|
+
to exclude its liability for matters which may not be excluded under that law. Usage: The
|
31
|
+
countryCode input parameter must follow the pattern [A-Z]{2} The vatNumber input parameter must
|
32
|
+
follow the [0-9A-Za-z\+\*\.]{2,12} In case of problem, the returned FaultString can take the
|
33
|
+
following specific values: - INVALID_INPUT: The provided CountryCode is invalid or the VAT
|
34
|
+
number is empty; - SERVICE_UNAVAILABLE: The SOAP service is unavailable, try again later; -
|
35
|
+
MS_UNAVAILABLE: The Member State service is unavailable, try again later or with another Member
|
36
|
+
State; - TIMEOUT: The Member State service could not be reach in time, try again later or with
|
37
|
+
another Member State; - SERVER_BUSY: The service can't process your request. Try again latter.
|
38
|
+
</xsd:documentation>
|
39
|
+
|
40
|
+
<wsdl:types>
|
41
|
+
<xsd:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="urn:ec.europa.eu:taxud:vies:services:checkVat:types" xmlns="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
|
42
|
+
<xsd:element name="checkVat">
|
43
|
+
<xsd:complexType>
|
44
|
+
<xsd:sequence>
|
45
|
+
<xsd:element name="countryCode" type="xsd:string"/>
|
46
|
+
<xsd:element name="vatNumber" type="xsd:string"/>
|
47
|
+
</xsd:sequence>
|
48
|
+
</xsd:complexType>
|
49
|
+
</xsd:element>
|
50
|
+
<xsd:element name="checkVatResponse">
|
51
|
+
<xsd:complexType>
|
52
|
+
<xsd:sequence>
|
53
|
+
<xsd:element name="countryCode" type="xsd:string"/>
|
54
|
+
<xsd:element name="vatNumber" type="xsd:string"/>
|
55
|
+
<xsd:element name="requestDate" type="xsd:date"/>
|
56
|
+
<xsd:element name="valid" type="xsd:boolean"/>
|
57
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="name" nillable="true" type="xsd:string"/>
|
58
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="address" nillable="true" type="xsd:string"/>
|
59
|
+
</xsd:sequence>
|
60
|
+
</xsd:complexType>
|
61
|
+
</xsd:element>
|
62
|
+
<xsd:element name="checkVatApprox">
|
63
|
+
<xsd:complexType>
|
64
|
+
<xsd:sequence>
|
65
|
+
<xsd:element name="countryCode" type="xsd:string"/>
|
66
|
+
<xsd:element name="vatNumber" type="xsd:string"/>
|
67
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderName" type="xsd:string"/>
|
68
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyType" type="tns1:companyTypeCode"/>
|
69
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderStreet" type="xsd:string"/>
|
70
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderPostcode" type="xsd:string"/>
|
71
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCity" type="xsd:string"/>
|
72
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="requesterCountryCode" type="xsd:string"/>
|
73
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="requesterVatNumber" type="xsd:string"/>
|
74
|
+
</xsd:sequence>
|
75
|
+
</xsd:complexType>
|
76
|
+
</xsd:element>
|
77
|
+
<xsd:element name="checkVatApproxResponse">
|
78
|
+
<xsd:complexType>
|
79
|
+
<xsd:sequence>
|
80
|
+
<xsd:element name="countryCode" type="xsd:string"/>
|
81
|
+
<xsd:element name="vatNumber" type="xsd:string"/>
|
82
|
+
<xsd:element name="requestDate" type="xsd:date"/>
|
83
|
+
<xsd:element name="valid" type="xsd:boolean"/>
|
84
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderName" nillable="true" type="xsd:string"/>
|
85
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyType" nillable="true" type="tns1:companyTypeCode"/>
|
86
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderAddress" type="xsd:string"/>
|
87
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderStreet" type="xsd:string"/>
|
88
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderPostcode" type="xsd:string"/>
|
89
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCity" type="xsd:string"/>
|
90
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderNameMatch" type="tns1:matchCode"/>
|
91
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyTypeMatch" type="tns1:matchCode"/>
|
92
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderStreetMatch" type="tns1:matchCode"/>
|
93
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderPostcodeMatch" type="tns1:matchCode"/>
|
94
|
+
<xsd:element maxOccurs="1" minOccurs="0" name="traderCityMatch" type="tns1:matchCode"/>
|
95
|
+
<xsd:element name="requestIdentifier" type="xsd:string"/>
|
96
|
+
</xsd:sequence>
|
97
|
+
</xsd:complexType>
|
98
|
+
</xsd:element>
|
99
|
+
<xsd:simpleType name="companyTypeCode">
|
100
|
+
<xsd:restriction base="xsd:string">
|
101
|
+
<xsd:pattern value="[A-Z]{2}\-[1-9][0-9]?"/>
|
102
|
+
</xsd:restriction>
|
103
|
+
</xsd:simpleType>
|
104
|
+
<xsd:simpleType name="matchCode">
|
105
|
+
<xsd:restriction base="xsd:string">
|
106
|
+
<xsd:enumeration value="1">
|
107
|
+
<xsd:annotation>
|
108
|
+
<xsd:documentation>VALID</xsd:documentation>
|
109
|
+
</xsd:annotation>
|
110
|
+
</xsd:enumeration>
|
111
|
+
<xsd:enumeration value="2">
|
112
|
+
<xsd:annotation>
|
113
|
+
<xsd:documentation>INVALID</xsd:documentation>
|
114
|
+
</xsd:annotation>
|
115
|
+
</xsd:enumeration>
|
116
|
+
</xsd:restriction>
|
117
|
+
</xsd:simpleType>
|
118
|
+
</xsd:schema>
|
119
|
+
</wsdl:types>
|
120
|
+
<wsdl:message name="checkVatRequest">
|
121
|
+
<wsdl:part name="parameters" element="tns1:checkVat">
|
122
|
+
</wsdl:part>
|
123
|
+
</wsdl:message>
|
124
|
+
<wsdl:message name="checkVatApproxResponse">
|
125
|
+
<wsdl:part name="parameters" element="tns1:checkVatApproxResponse">
|
126
|
+
</wsdl:part>
|
127
|
+
</wsdl:message>
|
128
|
+
<wsdl:message name="checkVatApproxRequest">
|
129
|
+
<wsdl:part name="parameters" element="tns1:checkVatApprox">
|
130
|
+
</wsdl:part>
|
131
|
+
</wsdl:message>
|
132
|
+
<wsdl:message name="checkVatResponse">
|
133
|
+
<wsdl:part name="parameters" element="tns1:checkVatResponse">
|
134
|
+
</wsdl:part>
|
135
|
+
</wsdl:message>
|
136
|
+
<wsdl:portType name="checkVatPortType">
|
137
|
+
<wsdl:operation name="checkVat">
|
138
|
+
<wsdl:input name="checkVatRequest" message="impl:checkVatRequest">
|
139
|
+
</wsdl:input>
|
140
|
+
<wsdl:output name="checkVatResponse" message="impl:checkVatResponse">
|
141
|
+
</wsdl:output>
|
142
|
+
</wsdl:operation>
|
143
|
+
<wsdl:operation name="checkVatApprox">
|
144
|
+
<wsdl:input name="checkVatApproxRequest" message="impl:checkVatApproxRequest">
|
145
|
+
</wsdl:input>
|
146
|
+
<wsdl:output name="checkVatApproxResponse" message="impl:checkVatApproxResponse">
|
147
|
+
</wsdl:output>
|
148
|
+
</wsdl:operation>
|
149
|
+
</wsdl:portType>
|
150
|
+
<wsdl:binding name="checkVatBinding" type="impl:checkVatPortType">
|
151
|
+
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
152
|
+
<wsdl:operation name="checkVat">
|
153
|
+
<wsdlsoap:operation soapAction=""/>
|
154
|
+
<wsdl:input name="checkVatRequest">
|
155
|
+
<wsdlsoap:body use="literal"/>
|
156
|
+
</wsdl:input>
|
157
|
+
<wsdl:output name="checkVatResponse">
|
158
|
+
<wsdlsoap:body use="literal"/>
|
159
|
+
</wsdl:output>
|
160
|
+
</wsdl:operation>
|
161
|
+
<wsdl:operation name="checkVatApprox">
|
162
|
+
<wsdlsoap:operation soapAction=""/>
|
163
|
+
<wsdl:input name="checkVatApproxRequest">
|
164
|
+
<wsdlsoap:body use="literal"/>
|
165
|
+
</wsdl:input>
|
166
|
+
<wsdl:output name="checkVatApproxResponse">
|
167
|
+
<wsdlsoap:body use="literal"/>
|
168
|
+
</wsdl:output>
|
169
|
+
</wsdl:operation>
|
170
|
+
</wsdl:binding>
|
171
|
+
<wsdl:service name="checkVatService">
|
172
|
+
<wsdl:port name="checkVatPort" binding="impl:checkVatBinding">
|
173
|
+
<wsdlsoap:address location="http://ec.europa.eu/taxation_customs/vies/services/checkVatService"/>
|
174
|
+
</wsdl:port>
|
175
|
+
</wsdl:service>
|
176
|
+
</wsdl:definitions>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LogInterceptor
|
4
|
+
@@intercepted_request = ""
|
5
|
+
def self.debug(message = nil)
|
6
|
+
message ||= yield if block_given?
|
7
|
+
|
8
|
+
# save only the first XMLly message
|
9
|
+
if message.include? "xml version"
|
10
|
+
@@intercepted_request = message if @@intercepted_request == ""
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.info(message = nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_intercepted_request
|
18
|
+
@@intercepted_request
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.reset_intercepted_request
|
22
|
+
@@intercepted_request = ""
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'Correct translation of attributes to XML' do
|
27
|
+
it "new :@attr syntax: correctly maps a Ruby Hash to XML attributes" do
|
28
|
+
LogInterceptor.reset_intercepted_request
|
29
|
+
|
30
|
+
client = Savon.client(
|
31
|
+
:wsdl => "http://mt205.sabameeting.com/CWS/CWS.asmx?WSDL",
|
32
|
+
:log => true,
|
33
|
+
:logger => LogInterceptor
|
34
|
+
)
|
35
|
+
|
36
|
+
response = nil
|
37
|
+
begin
|
38
|
+
response = call_and_fail_gracefully(client, :add_new_user, :message => { :user => { :@userID => "test" } })
|
39
|
+
rescue
|
40
|
+
end
|
41
|
+
|
42
|
+
xml_doc = Nokogiri::XML(LogInterceptor.get_intercepted_request)
|
43
|
+
xml_doc.remove_namespaces!
|
44
|
+
|
45
|
+
attributes_element_not_present = xml_doc.xpath("//AddNewUser/attributes").blank?
|
46
|
+
expect(attributes_element_not_present).to eq true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "old :attributes! syntax: correctly maps a Ruby Hash to XML attributes" do
|
50
|
+
LogInterceptor.reset_intercepted_request
|
51
|
+
|
52
|
+
client = Savon.client(
|
53
|
+
:wsdl => "http://mt205.sabameeting.com/CWS/CWS.asmx?WSDL",
|
54
|
+
:log => true,
|
55
|
+
:logger => LogInterceptor
|
56
|
+
)
|
57
|
+
|
58
|
+
response = nil
|
59
|
+
response = call_and_fail_gracefully(client, :add_new_user, :message => { :user => {}, :attributes! => { :user => { :userID => "test" } } })
|
60
|
+
|
61
|
+
xml_doc = Nokogiri::XML(LogInterceptor.get_intercepted_request)
|
62
|
+
xml_doc.remove_namespaces!
|
63
|
+
|
64
|
+
attributes_element_not_present = xml_doc.xpath("//AddNewUser/attributes").blank?
|
65
|
+
expect(attributes_element_not_present).to eq true
|
66
|
+
end
|
67
|
+
end
|
@@ -25,7 +25,7 @@ describe "Email example" do
|
|
25
25
|
pending "API limit exceeded"
|
26
26
|
else
|
27
27
|
# The expected result. We unfortunately don't have a license key for this service.
|
28
|
-
response_text.
|
28
|
+
expect(response_text).to eq("Email Domain Not Found")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'rpc/encoded binding test' do
|
4
|
+
|
5
|
+
it 'should should work with WSDLs that have rpc/encoded SOAP binding' do
|
6
|
+
client = Savon.client(
|
7
|
+
:wsdl => "http://www.boyzoid.com/comp/randomQuote.cfc?wsdl",
|
8
|
+
:open_timeout => 10,
|
9
|
+
:read_timeout => 10,
|
10
|
+
:log => false
|
11
|
+
)
|
12
|
+
|
13
|
+
begin
|
14
|
+
client.call(:get_quote)
|
15
|
+
rescue Savon::SOAPFault => e
|
16
|
+
$stderr.puts e.to_hash.inspect
|
17
|
+
f_c = e.to_hash[:fault][:faultstring]
|
18
|
+
expect(f_c).not_to eq('No such operation \'getQuoteRequest\'')
|
19
|
+
expect(f_c).to eq('lucee.runtime.exp.DatabaseException: ')
|
20
|
+
pending e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -19,10 +19,16 @@ describe "Stockquote example" do
|
|
19
19
|
|
20
20
|
cdata = response.body[:get_quote_response][:get_quote_result]
|
21
21
|
|
22
|
+
if cdata == "exception"
|
23
|
+
# Fallback to not fail the specs when the service's API limit is reached,
|
24
|
+
# but to mark the spec as pending instead.
|
25
|
+
pending "Exception on API"
|
26
|
+
end
|
27
|
+
|
22
28
|
nori_options = { :convert_tags_to => lambda { |tag| tag.snakecase.to_sym } }
|
23
29
|
result = Nori.new(nori_options).parse(cdata)
|
24
30
|
|
25
|
-
result[:stock_quotes][:stock][:symbol].
|
31
|
+
expect(result[:stock_quotes][:stock][:symbol]).to eq("AAPL")
|
26
32
|
end
|
27
33
|
|
28
34
|
end
|
data/spec/savon/builder_spec.rb
CHANGED
@@ -82,6 +82,56 @@ describe Savon::Builder do
|
|
82
82
|
expect(builder.to_s).to include("<tns:username>luke</tns:username>")
|
83
83
|
end
|
84
84
|
|
85
|
+
describe "#wsse_signature" do
|
86
|
+
fixture_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'ssl')
|
87
|
+
|
88
|
+
let(:cert) { File.join(fixture_dir, 'client_cert.pem') }
|
89
|
+
let(:private_key) { File.join(fixture_dir, 'client_key.pem') }
|
90
|
+
let(:signature) do
|
91
|
+
Akami::WSSE::Signature.new(
|
92
|
+
Akami::WSSE::Certs.new(
|
93
|
+
:cert_file => cert,
|
94
|
+
:private_key_file => private_key
|
95
|
+
)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
let(:globals) { Savon::GlobalOptions.new(wsse_signature: signature) }
|
99
|
+
|
100
|
+
subject(:signed_message_nn) {Nokogiri::XML(builder.to_s).remove_namespaces!}
|
101
|
+
subject(:signed_message) {Nokogiri::XML(builder.to_s)}
|
102
|
+
|
103
|
+
it "should contain a header" do
|
104
|
+
expect(signed_message_nn.xpath('/Envelope/Header').size).to eq(1)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should contain a wsse:Security" do
|
108
|
+
expect(signed_message_nn.xpath('/Envelope/Header/Security').size).to eq(1)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should have a Body[@wsu:Id]" do
|
112
|
+
#must investigate: acts funny in mri ruby
|
113
|
+
#expect(signed_message.xpath('//soapenv:Body', soapenv: "http://schemas.xmlsoap.org/soap/envelope/").attribute('ws:Id').value).to include('Body-')
|
114
|
+
expect(signed_message_nn.xpath('//Body').attr('Id').value).to include('Body-')
|
115
|
+
end
|
116
|
+
|
117
|
+
it "signature should be valid" do
|
118
|
+
certs = Akami::WSSE::Certs.new(:cert_file => cert, :private_key_file => private_key)
|
119
|
+
signature_value = signed_message_nn.xpath('//SignatureValue').text
|
120
|
+
signed_info_fragment = signed_message.xpath('//default:SignedInfo', default: "http://www.w3.org/2000/09/xmldsig#").to_xml
|
121
|
+
data = Nokogiri::XML(signed_info_fragment){|config| config.options = Nokogiri::XML::ParseOptions::NOBLANKS}
|
122
|
+
data.root.default_namespace='http://www.w3.org/2000/09/xmldsig#'
|
123
|
+
|
124
|
+
signed_info = data.canonicalize Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
|
125
|
+
|
126
|
+
signature = certs.private_key.sign(OpenSSL::Digest::SHA1.new, signed_info)
|
127
|
+
expect(Base64.encode64(signature).gsub("\n", '')).to eq(signature_value)
|
128
|
+
end
|
129
|
+
end
|
85
130
|
end
|
86
131
|
|
132
|
+
describe '#body_attributes' do
|
133
|
+
it 'should not be nil' do
|
134
|
+
expect(builder.body_attributes).to eq({})
|
135
|
+
end
|
136
|
+
end
|
87
137
|
end
|
data/spec/savon/client_spec.rb
CHANGED
@@ -62,6 +62,11 @@ describe Savon::Client do
|
|
62
62
|
it "returns the current set of global options" do
|
63
63
|
expect(new_client.globals).to be_an_instance_of(Savon::GlobalOptions)
|
64
64
|
end
|
65
|
+
|
66
|
+
fit "defaults :log to false" do
|
67
|
+
client = Savon.client(:wsdl => Fixture.wsdl(:authentication))
|
68
|
+
expect(client.globals[:log]).to be_falsey
|
69
|
+
end
|
65
70
|
end
|
66
71
|
|
67
72
|
describe "#service_name" do
|
@@ -165,6 +170,79 @@ describe Savon::Client do
|
|
165
170
|
end
|
166
171
|
end
|
167
172
|
|
173
|
+
describe "#build_request" do
|
174
|
+
it "returns the request without making an actual call" do
|
175
|
+
expected_request = mock('request')
|
176
|
+
wsdl = Wasabi::Document.new('http://example.com')
|
177
|
+
|
178
|
+
operation = Savon::Operation.new(
|
179
|
+
:authenticate,
|
180
|
+
wsdl,
|
181
|
+
Savon::GlobalOptions.new
|
182
|
+
)
|
183
|
+
operation.expects(:request).returns(expected_request)
|
184
|
+
|
185
|
+
Savon::Operation.expects(:create).with(
|
186
|
+
:authenticate,
|
187
|
+
instance_of(Wasabi::Document),
|
188
|
+
instance_of(Savon::GlobalOptions)
|
189
|
+
).returns(operation)
|
190
|
+
|
191
|
+
operation.expects(:call).never
|
192
|
+
|
193
|
+
client = new_client(:endpoint => @server.url(:repeat))
|
194
|
+
request = client.build_request(:authenticate) do
|
195
|
+
message(:symbol => "AAPL" )
|
196
|
+
end
|
197
|
+
|
198
|
+
expect(request).to eq expected_request
|
199
|
+
end
|
200
|
+
|
201
|
+
it "accepts a block without arguments" do
|
202
|
+
client = new_client(:endpoint => @server.url(:repeat))
|
203
|
+
request = client.build_request(:authenticate) do
|
204
|
+
message(:symbol => "AAPL" )
|
205
|
+
end
|
206
|
+
|
207
|
+
expect(request.body).
|
208
|
+
to include('<tns:authenticate><symbol>AAPL</symbol></tns:authenticate>')
|
209
|
+
end
|
210
|
+
|
211
|
+
it "accepts a block with one argument" do
|
212
|
+
client = new_client(:endpoint => @server.url(:repeat))
|
213
|
+
|
214
|
+
# supports instance variables!
|
215
|
+
@instance_variable = { :symbol => "AAPL" }
|
216
|
+
|
217
|
+
request = client.build_request(:authenticate) do |locals|
|
218
|
+
locals.message(@instance_variable)
|
219
|
+
end
|
220
|
+
|
221
|
+
expect(request.body).
|
222
|
+
to include("<tns:authenticate><symbol>AAPL</symbol></tns:authenticate>")
|
223
|
+
end
|
224
|
+
|
225
|
+
it "accepts argument for the message tag" do
|
226
|
+
client = new_client(:endpoint => @server.url(:repeat))
|
227
|
+
request = client.build_request(:authenticate, :attributes => { "ID" => "ABC321" })
|
228
|
+
|
229
|
+
expect(request.body).
|
230
|
+
to include("<tns:authenticate ID=\"ABC321\"></tns:authenticate>")
|
231
|
+
end
|
232
|
+
|
233
|
+
it "raises when the operation name is not a symbol" do
|
234
|
+
expect { new_client.build_request("not a symbol") }.to raise_error
|
235
|
+
end
|
236
|
+
|
237
|
+
it "raises when given an unknown option via the Hash syntax" do
|
238
|
+
expect { new_client.build_request(:authenticate, :invalid_local_option => true) }.to raise_error
|
239
|
+
end
|
240
|
+
|
241
|
+
it "raises when given an unknown option via the block syntax" do
|
242
|
+
expect { new_client.build_request(:authenticate) { another_invalid_local_option true } }.to raise_error
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
168
246
|
def new_http_response(options = {})
|
169
247
|
defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
|
170
248
|
response = defaults.merge options
|