lolsoap 0.1.4 → 0.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.
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0"?>
2
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <soap:Body>
4
+ <soap:Fault>
5
+ <soap:faultcode>soap:Sender</soap:faultcode>
6
+ <soap:faultstring>Omg! stock market has crashed!</soap:faultstring>
7
+ <soap:detail><Foo>Some detail</Foo></soap:detail>
8
+ </soap:Fault>
9
+ </soap:Body>
10
+ </soap:Envelope>
@@ -21,6 +21,7 @@ module LolSoap
21
21
  s.name 'LOCOLOCOLOCO'
22
22
  end
23
23
  b.lol
24
+ b.id 42
24
25
  end
25
26
 
26
27
  el = doc.at_xpath('//xsd1:TradePriceRequest/xsd1:tickerSymbol', doc.namespaces)
@@ -30,6 +31,9 @@ module LolSoap
30
31
  el = doc.at_xpath('//xsd1:TradePriceRequest/xsd1:specialTickerSymbol/xsd2:name', doc.namespaces)
31
32
  el.wont_equal nil
32
33
  el.text.to_s.must_equal 'LOCOLOCOLOCO'
34
+
35
+ attr = doc.at_xpath('//xsd1:TradePriceRequest/@id', doc.namespaces)
36
+ attr.to_s.must_equal "42"
33
37
  end
34
38
 
35
39
  it 'creates some header' do
@@ -8,14 +8,13 @@ module LolSoap
8
8
  it 'should successfully parse a WSDL document' do
9
9
  subject.operations.length.must_equal 1
10
10
  subject.operations['GetLastTradePrice'].tap do |o|
11
- o.input.must_equal subject.types['TradePriceRequest']
11
+ o.input.must_equal subject.types['xsd1:TradePriceRequest']
12
12
  o.action.must_equal 'http://example.com/GetLastTradePrice'
13
13
  end
14
14
 
15
15
  subject.types.length.must_equal 3
16
- subject.types['TradePriceRequest'].tap do |t|
17
- t.name.must_equal 'TradePriceRequest'
18
- t.namespace.must_equal 'http://example.com/stockquote.xsd'
16
+ subject.types['xsd1:TradePriceRequest'].tap do |t|
17
+ t.prefix.must_equal 'xsd1'
19
18
  end
20
19
  end
21
20
 
@@ -15,6 +15,7 @@ module LolSoap
15
15
  end
16
16
  let(:type) do
17
17
  type = OpenStruct.new(:prefix => 'a')
18
+ def type.has_attribute?(*); false; end
18
19
  def type.sub_type(name)
19
20
  @sub_types ||= { 'foo' => Object.new, 'bar' => Object.new, 'clone' => Object.new }
20
21
  @sub_types[name]
@@ -3,7 +3,13 @@ require 'lolsoap/envelope'
3
3
 
4
4
  module LolSoap
5
5
  describe Envelope do
6
- let(:wsdl) { OpenStruct.new(:type_namespaces => { 'foo' => 'http://example.com/foo' }) }
6
+ let(:wsdl) do
7
+ OpenStruct.new(
8
+ :type_namespaces => { 'foo' => 'http://example.com/foo' },
9
+ :soap_version => '1.2'
10
+ )
11
+ end
12
+
7
13
  let(:operation) do
8
14
  OpenStruct.new(:input => OpenStruct.new(:prefix => 'foo', :name => 'WashHandsRequest'))
9
15
  end
@@ -16,7 +22,7 @@ module LolSoap
16
22
 
17
23
  it 'has a skeleton SOAP envelope structure when first created' do
18
24
  doc.namespaces.must_equal(
19
- 'xmlns:soap' => Envelope::SOAP_NAMESPACE,
25
+ 'xmlns:soap' => Envelope::SOAP_1_2,
20
26
  'xmlns:foo' => 'http://example.com/foo'
21
27
  )
22
28
 
@@ -84,7 +90,11 @@ module LolSoap
84
90
 
85
91
  describe '#to_xml' do
86
92
  it 'returns the xml of the doc' do
87
- def subject.doc; OpenStruct.new(:to_xml => '<lol>'); end
93
+ def subject.doc
94
+ doc = Object.new
95
+ def doc.to_xml(options); '<lol>'; end
96
+ doc
97
+ end
88
98
  subject.to_xml.must_equal '<lol>'
89
99
  end
90
100
  end
@@ -108,5 +118,15 @@ module LolSoap
108
118
  subject.output_type.must_equal 'lol'
109
119
  end
110
120
  end
121
+
122
+ describe '#soap_namespace' do
123
+ it 'returns the correct envelope namespace according to the SOAP version' do
124
+ wsdl.soap_version = '1.2'
125
+ subject.soap_namespace.must_equal Envelope::SOAP_1_2
126
+
127
+ wsdl.soap_version = '1.1'
128
+ subject.soap_namespace.must_equal Envelope::SOAP_1_1
129
+ end
130
+ end
111
131
  end
112
132
  end
@@ -4,30 +4,48 @@ require 'lolsoap/fault'
4
4
 
5
5
  module LolSoap
6
6
  describe Fault do
7
- let(:request) { OpenStruct.new(:soap_namespace => Envelope::SOAP_NAMESPACE) }
8
- let(:node) do
9
- doc = Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote_fault.xml'))
10
- doc.at_xpath('//soap:Fault', 'soap' => Envelope::SOAP_NAMESPACE)
11
- end
7
+ examples = proc do
8
+ describe '#code' do
9
+ it 'returns the code' do
10
+ subject.code.must_equal 'soap:Sender'
11
+ end
12
+ end
12
13
 
13
- subject { Fault.new(request, node) }
14
+ describe '#reason' do
15
+ it 'returns the reason' do
16
+ subject.reason.must_match(/^Omg.*crashed!$/)
17
+ end
18
+ end
14
19
 
15
- describe '#code' do
16
- it 'returns the code' do
17
- subject.code.must_equal 'soap:Sender'
20
+ describe '#detail' do
21
+ it 'returns the detail' do
22
+ subject.detail.must_equal '<Foo>Some detail</Foo>'
23
+ end
18
24
  end
19
25
  end
20
26
 
21
- describe '#reason' do
22
- it 'returns the reason' do
23
- subject.reason.must_match(/^Omg.*crashed!$/)
27
+ describe 'SOAP 1.1' do
28
+ let(:request) { OpenStruct.new(:soap_version => '1.2', :soap_namespace => Envelope::SOAP_1_2) }
29
+ let(:node) do
30
+ doc = Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote_fault.xml'))
31
+ doc.at_xpath('//soap:Fault', 'soap' => Envelope::SOAP_1_2)
24
32
  end
33
+
34
+ subject { Fault.new(request, node) }
35
+
36
+ instance_eval(&examples)
25
37
  end
26
38
 
27
- describe '#detail' do
28
- it 'returns the detail' do
29
- subject.detail.must_equal '<Foo>Some detail</Foo>'
39
+ describe 'SOAP 1.2' do
40
+ let(:request) { OpenStruct.new(:soap_version => '1.1', :soap_namespace => Envelope::SOAP_1_1) }
41
+ let(:node) do
42
+ doc = Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote_fault_soap_1_1.xml'))
43
+ doc.at_xpath('//soap:Fault', 'soap' => Envelope::SOAP_1_1)
30
44
  end
45
+
46
+ subject { Fault.new(request, node) }
47
+
48
+ instance_eval(&examples)
31
49
  end
32
50
  end
33
51
  end
@@ -6,18 +6,6 @@ module LolSoap
6
6
  let(:envelope) { OpenStruct.new }
7
7
  subject { Request.new(envelope) }
8
8
 
9
- [:header, :body, :soap_namespace, :input_type, :output_type].each do |method|
10
- describe "##{method}" do
11
- let(:envelope) { MiniTest::Mock.new }
12
-
13
- it 'delegates to the envelope' do
14
- ret = Object.new
15
- envelope.expect(method, ret)
16
- subject.send(method).must_equal ret
17
- end
18
- end
19
- end
20
-
21
9
  describe '#url' do
22
10
  it 'returns the envelope endpoint' do
23
11
  envelope.endpoint = 'lol'
@@ -27,7 +15,7 @@ module LolSoap
27
15
 
28
16
  describe '#headers' do
29
17
  it 'returns the necessary headers' do
30
- envelope.to_xml = '<lol>'
18
+ def envelope.to_xml(options); '<lol>'; end
31
19
  envelope.action = 'http://example.com/LolOutLoud'
32
20
 
33
21
  subject.headers.must_equal({
@@ -40,9 +28,21 @@ module LolSoap
40
28
 
41
29
  describe '#content' do
42
30
  it 'returns the envelope as an xml string' do
43
- envelope.to_xml = '<lol>'
31
+ def envelope.to_xml(options); '<lol>'; end
44
32
  subject.content.must_equal '<lol>'
45
33
  end
46
34
  end
35
+
36
+ describe '#mime' do
37
+ it 'is application/soap+xml for SOAP 1.2' do
38
+ envelope.soap_version = '1.2'
39
+ subject.mime.must_equal 'application/soap+xml'
40
+ end
41
+
42
+ it 'is text/xml for SOAP 1.1' do
43
+ envelope.soap_version = '1.1'
44
+ subject.mime.must_equal 'text/xml'
45
+ end
46
+ end
47
47
  end
48
48
  end
@@ -4,7 +4,7 @@ require 'lolsoap/response'
4
4
 
5
5
  module LolSoap
6
6
  describe Response do
7
- let(:request) { OpenStruct.new(:soap_namespace => Envelope::SOAP_NAMESPACE, :output => Object.new) }
7
+ let(:request) { OpenStruct.new(:soap_namespace => Envelope::SOAP_1_2, :soap_version => '1.2', :output => Object.new) }
8
8
  let(:doc) { Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote_response.xml')) }
9
9
 
10
10
  subject { Response.new(request, doc) }
@@ -5,137 +5,118 @@ module LolSoap
5
5
  describe WSDL do
6
6
  describe 'with a doc that can be parsed' do
7
7
  let(:namespace) { 'http://lolsoap.api/bla' }
8
- let(:parser) { OpenStruct.new(:namespaces => { 'bla' => namespace }) }
9
8
 
10
- subject { WSDL.new(parser) }
11
-
12
- describe 'with operations' do
13
- before do
14
- def subject.type(n)
15
- @types ||= { 'WashHandsRequest' => Object.new, 'WashHandsResponse' => Object.new }
16
- @types[n]
17
- end
18
-
19
- parser.operations = {
9
+ let(:parser) do
10
+ OpenStruct.new(
11
+ :namespaces => { 'bla' => namespace },
12
+ :operations => {
20
13
  'washHands' => {
21
14
  :action => 'urn:washHands',
22
- :input => { :name => 'WashHandsRequest' },
23
- :output => { :name => 'WashHandsResponse' }
15
+ :input => 'bla:Brush',
16
+ :output => 'bla:Color'
24
17
  }
25
- }
26
- end
27
-
28
- describe '#operations' do
29
- it 'returns a hash of operations' do
30
- subject.operations.length.must_equal 1
31
- subject.operations['washHands'].tap do |op|
32
- op.wsdl.must_equal subject
33
- op.action.must_equal "urn:washHands"
34
- op.input.must_equal subject.types['WashHandsRequest']
35
- op.output.must_equal subject.types['WashHandsResponse']
36
- end
37
- end
38
- end
39
-
40
- describe '#operation' do
41
- it 'returns a single operation' do
42
- subject.operation('washHands').must_equal subject.operations['washHands']
43
- end
44
- end
45
- end
46
-
47
- describe '#endpoint' do
48
- it 'returns the endpoint' do
49
- parser.endpoint = 'http://lolsoap.api/v1'
50
- subject.endpoint.must_equal 'http://lolsoap.api/v1'
51
- end
52
- end
53
-
54
- describe '#namespaces' do
55
- it 'returns a namespaces hash' do
56
- subject.namespaces.must_equal({ 'bla' => namespace })
57
- end
58
- end
59
-
60
- describe '#prefixes' do
61
- it 'returns the prefixes-to-namespace mapping' do
62
- subject.prefixes.must_equal({ namespace => 'bla' })
63
- end
64
- end
65
-
66
- describe 'with types' do
67
- before do
68
- parser.types = {
69
- 'Brush' => {
18
+ },
19
+ :types => {
20
+ 'bla:Brush' => {
70
21
  :elements => {
71
22
  'handleColor' => {
72
- :name => 'handleColor',
73
23
  :type => 'bla:Color',
74
24
  :singular => true
75
25
  },
76
26
  'age' => {
77
- :name => 'age',
78
27
  :type => 'xs:int',
79
28
  :singular => false
80
29
  }
81
30
  },
82
- :namespace => namespace
31
+ :attributes => ['id'],
32
+ :prefix => 'bla'
83
33
  },
84
- 'Color' => {
34
+ 'bla:Color' => {
85
35
  :elements => {
86
36
  'name' => {
87
- :name => 'name',
88
37
  :type => 'xs:string',
89
38
  :singular => true
90
39
  },
91
40
  'hex' => {
92
- :name => 'hex',
93
41
  :type => 'xs:string',
94
42
  :singular => true
95
43
  }
96
44
  },
97
- :namespace => namespace
45
+ :attributes => [],
46
+ :prefix => 'bla'
98
47
  }
99
48
  }
49
+ )
50
+ end
51
+
52
+ subject { WSDL.new(parser) }
53
+
54
+ describe '#operations' do
55
+ it 'returns a hash of operations' do
56
+ subject.operations.length.must_equal 1
57
+ subject.operations['washHands'].tap do |op|
58
+ op.wsdl.must_equal subject
59
+ op.action.must_equal "urn:washHands"
60
+ op.input.must_equal subject.types['bla:Brush']
61
+ op.output.must_equal subject.types['bla:Color']
62
+ end
100
63
  end
64
+ end
101
65
 
102
- describe '#types' do
103
- it 'returns a hash of types' do
104
- subject.types.length.must_equal 2
66
+ describe '#operation' do
67
+ it 'returns a single operation' do
68
+ subject.operation('washHands').must_equal subject.operations['washHands']
69
+ end
70
+ end
105
71
 
106
- subject.types['Brush'].tap do |t|
107
- t.namespace.must_equal namespace
108
- t.elements.length.must_equal 2
109
- t.element('handleColor').type.must_equal subject.types['Color']
110
- t.element('handleColor').singular?.must_equal true
111
- t.element('age').type.must_equal WSDL::NullType.new
112
- t.element('age').singular?.must_equal false
113
- end
72
+ describe '#endpoint' do
73
+ it 'returns the endpoint' do
74
+ parser.endpoint = 'http://lolsoap.api/v1'
75
+ subject.endpoint.must_equal 'http://lolsoap.api/v1'
76
+ end
77
+ end
114
78
 
115
- subject.types['Color'].tap do |t|
116
- t.namespace.must_equal namespace
117
- t.elements.length.must_equal 2
118
- t.element('name').type.must_equal WSDL::NullType.new
119
- t.element('hex').type.must_equal WSDL::NullType.new
120
- end
121
- end
79
+ describe '#namespaces' do
80
+ it 'returns a namespaces hash' do
81
+ subject.namespaces.must_equal({ 'bla' => namespace })
122
82
  end
83
+ end
123
84
 
124
- describe '#type' do
125
- it 'returns a single type' do
126
- subject.type('Color').must_equal subject.types['Color']
85
+ describe '#types' do
86
+ it 'returns a hash of types' do
87
+ subject.types.length.must_equal 2
88
+
89
+ subject.types['bla:Brush'].tap do |t|
90
+ t.elements.length.must_equal 2
91
+ t.element('handleColor').type.must_equal subject.types['bla:Color']
92
+ t.element('handleColor').singular?.must_equal true
93
+ t.element('age').type.must_equal WSDL::NullType.new
94
+ t.element('age').singular?.must_equal false
95
+ t.attributes.must_equal ['id']
127
96
  end
128
97
 
129
- it 'returns a null object if a type is missing' do
130
- subject.type('FooBar').must_equal WSDL::NullType.new
98
+ subject.types['bla:Color'].tap do |t|
99
+ t.elements.length.must_equal 2
100
+ t.element('name').type.must_equal WSDL::NullType.new
101
+ t.element('hex').type.must_equal WSDL::NullType.new
131
102
  end
132
103
  end
104
+ end
133
105
 
134
- describe '#type_namespaces' do
135
- it 'returns only the namespaces that used by types' do
136
- parser.namespaces['foo'] = 'bar'
137
- subject.type_namespaces.must_equal 'bla' => namespace
138
- end
106
+ describe '#type' do
107
+ it 'returns a single type' do
108
+ subject.type('bla:Color').must_equal subject.types['bla:Color']
109
+ end
110
+
111
+ it 'returns a null object if a type is missing' do
112
+ subject.type('FooBar').must_equal WSDL::NullType.new
113
+ end
114
+ end
115
+
116
+ describe '#type_namespaces' do
117
+ it 'returns only the namespaces that are used by types' do
118
+ parser.namespaces['foo'] = 'bar'
119
+ subject.type_namespaces.must_equal 'bla' => namespace
139
120
  end
140
121
  end
141
122
  end
@@ -3,7 +3,12 @@ require 'lolsoap/wsdl_parser'
3
3
 
4
4
  module LolSoap
5
5
  describe WSDLParser do
6
- let(:doc) { Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote.wsdl')) }
6
+ def raw_doc
7
+ File.read(TEST_ROOT + '/fixtures/stock_quote.wsdl')
8
+ end
9
+
10
+ let(:doc) { Nokogiri::XML(raw_doc) }
11
+
7
12
  subject { WSDLParser.new(doc) }
8
13
 
9
14
  describe '#namespaces' do
@@ -12,7 +17,9 @@ module LolSoap
12
17
  'tns' => 'http://example.com/stockquote.wsdl',
13
18
  'xsd1' => 'http://example.com/stockquote.xsd',
14
19
  'xsd2' => 'http://example.com/stockquote2.xsd',
15
- 'soap' => 'http://schemas.xmlsoap.org/wsdl/soap12/'
20
+ 'xsd3' => 'http://example.com/stockquote.xsd',
21
+ 'soap' => 'http://schemas.xmlsoap.org/wsdl/soap12/',
22
+ 'xs' => 'http://www.w3.org/2001/XMLSchema'
16
23
  })
17
24
  end
18
25
  end
@@ -26,43 +33,42 @@ module LolSoap
26
33
  describe '#types' do
27
34
  it 'returns the types, with attributes and namespace' do
28
35
  subject.types.must_equal({
29
- 'TradePriceRequest' => {
30
- :name => 'TradePriceRequest',
31
- :namespace => 'http://example.com/stockquote.xsd',
32
- :elements => {
36
+ 'xsd1:TradePriceRequest' => {
37
+ :prefix => 'xsd1',
38
+ :name => 'TradePriceRequest',
39
+ :elements => {
33
40
  'tickerSymbol' => {
34
- :name => 'tickerSymbol',
35
- :type => 'string',
41
+ :type => 'xs:string',
36
42
  :singular => false
37
43
  },
38
44
  'specialTickerSymbol' => {
39
- :name => 'specialTickerSymbol',
40
45
  :type => 'xsd2:TickerSymbol',
41
46
  :singular => false
42
47
  }
43
- }
48
+ },
49
+ :attributes => ['id']
44
50
  },
45
- 'TradePrice' => {
46
- :name => 'TradePrice',
47
- :namespace => 'http://example.com/stockquote.xsd',
48
- :elements => {
51
+ 'xsd1:TradePrice' => {
52
+ :prefix => 'xsd1',
53
+ :name => 'TradePrice',
54
+ :elements => {
49
55
  'price' => {
50
- :name => 'price',
51
- :type => 'float',
56
+ :type => 'xs:float',
52
57
  :singular => true
53
58
  }
54
- }
59
+ },
60
+ :attributes => []
55
61
  },
56
- 'TickerSymbol' => {
57
- :name => 'TickerSymbol',
58
- :namespace => 'http://example.com/stockquote2.xsd',
59
- :elements => {
62
+ 'xsd2:TickerSymbol' => {
63
+ :prefix => 'xsd2',
64
+ :name => 'TickerSymbol',
65
+ :elements => {
60
66
  'name' => {
61
- :name => 'name',
62
- :type => 'string',
67
+ :type => 'xs:string',
63
68
  :singular => true
64
69
  }
65
- }
70
+ },
71
+ :attributes => []
66
72
  }
67
73
  })
68
74
  end
@@ -71,8 +77,8 @@ module LolSoap
71
77
  describe '#messages' do
72
78
  it 'maps message names to types' do
73
79
  subject.messages.must_equal({
74
- 'GetLastTradePriceInput' => subject.types['TradePriceRequest'],
75
- 'GetLastTradePriceOutput' => subject.types['TradePrice']
80
+ 'GetLastTradePriceInput' => 'xsd1:TradePriceRequest',
81
+ 'GetLastTradePriceOutput' => 'xsd1:TradePrice'
76
82
  })
77
83
  end
78
84
  end
@@ -81,9 +87,8 @@ module LolSoap
81
87
  it 'is a hash containing input and output types' do
82
88
  subject.port_type_operations.must_equal({
83
89
  'GetLastTradePrice' => {
84
- :name => 'GetLastTradePrice',
85
- :input => subject.types['TradePriceRequest'],
86
- :output => subject.types['TradePrice']
90
+ :input => 'xsd1:TradePriceRequest',
91
+ :output => 'xsd1:TradePrice'
87
92
  }
88
93
  })
89
94
  end
@@ -93,13 +98,22 @@ module LolSoap
93
98
  it 'is a hash of operations with their action and input type' do
94
99
  subject.operations.must_equal({
95
100
  'GetLastTradePrice' => {
96
- :name => 'GetLastTradePrice',
97
101
  :action => 'http://example.com/GetLastTradePrice',
98
- :input => subject.types['TradePriceRequest'],
99
- :output => subject.types['TradePrice']
102
+ :input => 'xsd1:TradePriceRequest',
103
+ :output => 'xsd1:TradePrice'
100
104
  }
101
105
  })
102
106
  end
103
107
  end
108
+
109
+ describe 'soap 1.1' do
110
+ def raw_doc
111
+ super.sub("http://schemas.xmlsoap.org/wsdl/soap12/", "http://schemas.xmlsoap.org/wsdl/soap/")
112
+ end
113
+
114
+ it 'is supported' do
115
+ subject.operations.empty?.must_equal false
116
+ end
117
+ end
104
118
  end
105
119
  end
@@ -3,13 +3,13 @@ require 'lolsoap/wsdl'
3
3
 
4
4
  class LolSoap::WSDL
5
5
  describe Type do
6
- let(:wsdl) { OpenStruct.new(:prefixes => { 'http://example.com/foo' => 'foo' }) }
7
6
  let(:elements) { { 'soapColor' => OpenStruct.new(:type => Object.new) } }
8
- subject { Type.new(wsdl, 'WashHandsRequest', 'http://example.com/foo', elements) }
7
+
8
+ subject { Type.new('WashHandsRequest', 'prfx', elements, {}) }
9
9
 
10
10
  describe '#prefix' do
11
- it 'returns the prefix from the WSDL doc' do
12
- subject.prefix.must_equal 'foo'
11
+ it 'returns the prefix' do
12
+ subject.prefix.must_equal 'prfx'
13
13
  end
14
14
  end
15
15