diaspora-vines 0.1.26 → 0.1.27

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/conf/config.rb +1 -0
  3. data/lib/vines.rb +12 -5
  4. data/lib/vines/config/host.rb +9 -0
  5. data/lib/vines/kit.rb +7 -0
  6. data/lib/vines/node.rb +31 -0
  7. data/lib/vines/router.rb +5 -0
  8. data/lib/vines/stanza/presence.rb +16 -1
  9. data/lib/vines/storage.rb +10 -1
  10. data/lib/vines/storage/sql.rb +18 -5
  11. data/lib/vines/stream.rb +12 -10
  12. data/lib/vines/stream/client/bind_restart.rb +6 -0
  13. data/lib/vines/stream/http.rb +13 -11
  14. data/lib/vines/stream/server.rb +46 -13
  15. data/lib/vines/stream/server/auth_method.rb +78 -0
  16. data/lib/vines/stream/server/auth_restart.rb +27 -1
  17. data/lib/vines/stream/server/outbound/auth.rb +43 -9
  18. data/lib/vines/stream/server/outbound/auth_dialback_result.rb +39 -0
  19. data/lib/vines/stream/server/outbound/auth_external.rb +33 -0
  20. data/lib/vines/stream/server/outbound/{auth_result.rb → auth_external_result.rb} +1 -1
  21. data/lib/vines/stream/server/outbound/auth_restart.rb +8 -1
  22. data/lib/vines/stream/server/outbound/authoritative.rb +48 -0
  23. data/lib/vines/stream/server/outbound/start.rb +1 -1
  24. data/lib/vines/stream/server/start.rb +29 -2
  25. data/lib/vines/stream/state.rb +3 -17
  26. data/lib/vines/version.rb +1 -1
  27. data/test/storage/sql_test.rb +16 -0
  28. data/test/store_test.rb +3 -1
  29. data/test/stream/server/auth_method_test.rb +101 -0
  30. data/test/stream/server/outbound/auth_dialback_result_test.rb +37 -0
  31. data/test/stream/server/outbound/auth_external_test.rb +75 -0
  32. data/test/stream/server/outbound/auth_restart_test.rb +53 -0
  33. data/test/stream/server/outbound/auth_test.rb +59 -43
  34. data/test/stream/server/outbound/authoritative_test.rb +66 -0
  35. data/test/stream/server/outbound/start_test.rb +33 -0
  36. data/test/stream/server/start_test.rb +70 -0
  37. metadata +33 -10
  38. data/lib/vines/stream/server/outbound/tls.rb +0 -30
  39. data/lib/vines/stream/server/tls.rb +0 -13
data/test/store_test.rb CHANGED
@@ -120,7 +120,7 @@ describe Vines::Store do
120
120
 
121
121
  def certificate(domain, altname=nil)
122
122
  # Use small key so tests are fast.
123
- key = OpenSSL::PKey::RSA.generate(256)
123
+ key = OpenSSL::PKey::RSA.generate(512)
124
124
 
125
125
  name = OpenSSL::X509::Name.parse("/C=US/ST=Colorado/L=Denver/O=Test/CN=#{domain}")
126
126
  cert = OpenSSL::X509::Certificate.new
@@ -142,6 +142,8 @@ describe Vines::Store do
142
142
  ].map {|k, v| factory.create_ext(k, v) }
143
143
  end
144
144
 
145
+ cert.sign key, OpenSSL::Digest::SHA1.new
146
+
145
147
  Pair.new(cert.to_pem, key.to_pem)
146
148
  end
147
149
 
@@ -0,0 +1,101 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ class OperatorWrapper
6
+ def <<(stream)
7
+ [stream]
8
+ end
9
+ end
10
+
11
+ describe Vines::Stream::Server::AuthMethod do
12
+ before do
13
+ @result = {
14
+ from: 'hostA.org',
15
+ to: 'hostB.org',
16
+ token: '1234'
17
+ }
18
+ @stream = MiniTest::Mock.new
19
+ @state = Vines::Stream::Server::AuthMethod.new(@stream)
20
+ end
21
+
22
+ def test_invalid_element
23
+ node = node('<message/>')
24
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
25
+ end
26
+
27
+ def test_invalid_tls_element
28
+ node = node(%Q{<message xmlns="#{Vines::NAMESPACES[:tls]}"/>})
29
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
30
+ end
31
+
32
+ def test_invalid_dialback_element
33
+ node = node(%Q{<message xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}"/>})
34
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
35
+ end
36
+
37
+ def test_missing_tls_namespace
38
+ node = node('<starttls/>')
39
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
40
+ end
41
+
42
+ def test_no_dialback_payload
43
+ node = node('<db:result/>')
44
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
45
+ end
46
+
47
+ def test_invalid_tls_namespace
48
+ node = node(%Q{<starttls xmlns="#{Vines::NAMESPACES[:legacy_dialback]}"/>})
49
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
50
+ end
51
+
52
+ def test_missing_tls_certificate
53
+ @stream.expect(:encrypt?, false)
54
+ @stream.expect(:close_connection_after_writing, nil)
55
+ failure = %Q{<failure xmlns="#{Vines::NAMESPACES[:tls]}"/>}
56
+ node = node(%Q{<starttls xmlns="#{Vines::NAMESPACES[:tls]}"/>})
57
+ @stream.expect(:write, nil, [failure])
58
+ @stream.expect(:write, nil, ['</stream:stream>'])
59
+ @state.node(node)
60
+ assert @stream.verify
61
+ end
62
+
63
+ def test_valid_tls
64
+ @stream.expect(:encrypt?, true)
65
+ @stream.expect(:encrypt, nil)
66
+ @stream.expect(:reset, nil)
67
+ @stream.expect(:advance, nil, [Vines::Stream::Server::AuthRestart.new(@stream)])
68
+ success = %Q{<proceed xmlns="#{Vines::NAMESPACES[:tls]}"/>}
69
+ node = node(%Q{<starttls xmlns="#{Vines::NAMESPACES[:tls]}"/>})
70
+ @stream.expect(:write, nil, [success])
71
+ @state.node(node)
72
+ assert @stream.verify
73
+ end
74
+
75
+ def test_valid_dialback
76
+ @stream.expect(:config, Vines::Config)
77
+ @stream.expect(:router, OperatorWrapper.new)
78
+ @stream.expect(:close_connection_after_writing, nil)
79
+ node = node(%Q{
80
+ <db:result xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="#{@result[:from]}" to="#{@result[:to]}">
81
+ #{@result[:token]}
82
+ </db:result>
83
+ })
84
+ assert_nothing_raised do
85
+ @state.node(node)
86
+ end.must_equal(true)
87
+ end
88
+
89
+ private
90
+
91
+ def assert_nothing_raised
92
+ yield
93
+ true
94
+ rescue
95
+ $!
96
+ end
97
+
98
+ def node(xml)
99
+ Nokogiri::XML(xml).root
100
+ end
101
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stream::Server::Outbound::AuthDialbackResult do
6
+ before do
7
+ @stream = MiniTest::Mock.new
8
+ @state = Vines::Stream::Server::Outbound::AuthDialbackResult.new(@stream)
9
+ end
10
+
11
+ def test_invalid_stanza
12
+ node = node('<message/>')
13
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
14
+ assert @stream.verify
15
+ end
16
+
17
+ def test_invalid_result
18
+ node = node(%Q{<db:result xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" type="invalid"/>})
19
+ @stream.expect(:close_connection, nil)
20
+ @state.node(node)
21
+ assert @stream.verify
22
+ end
23
+
24
+ def test_valid_result
25
+ node = node(%Q{<db:result xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" type="valid"/>})
26
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Ready])
27
+ @stream.expect(:notify_connected, nil)
28
+ @state.node(node)
29
+ assert @stream.verify
30
+ end
31
+
32
+ private
33
+
34
+ def node(xml)
35
+ Nokogiri::XML(xml).root
36
+ end
37
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stream::Server::Outbound::AuthExternal do
6
+ before do
7
+ @stream = MiniTest::Mock.new
8
+ @state = Vines::Stream::Server::Outbound::AuthExternal.new(@stream)
9
+ end
10
+
11
+ def test_invalid_element
12
+ node = node('<message/>')
13
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
14
+ end
15
+
16
+ def test_invalid_sasl_element
17
+ node = node(%Q{<message xmlns="#{Vines::NAMESPACES[:sasl]}"/>})
18
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
19
+ end
20
+
21
+ def test_missing_namespace
22
+ node = node('<stream:features/>')
23
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
24
+ end
25
+
26
+ def test_invalid_namespace
27
+ node = node('<stream:features xmlns="bogus"/>')
28
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
29
+ end
30
+
31
+ def test_missing_mechanisms
32
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams"/>})
33
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
34
+ end
35
+
36
+ def test_missing_mechanisms_namespace
37
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams"><mechanisms/></stream:features>})
38
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
39
+ end
40
+
41
+ def test_missing_mechanism
42
+ mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>}
43
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
44
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
45
+ end
46
+
47
+ def test_missing_mechanism_text
48
+ mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism></mechanism></mechanisms>}
49
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
50
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
51
+ end
52
+
53
+ def test_invalid_mechanism_text
54
+ mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>BOGUS</mechanism></mechanisms>}
55
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
56
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
57
+ end
58
+
59
+ def test_valid_mechanism
60
+ @stream.expect(:domain, 'wonderland.lit')
61
+ expected = %Q{<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="EXTERNAL">d29uZGVybGFuZC5saXQ=</auth>}
62
+ @stream.expect(:write, nil, [expected])
63
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::AuthExternalResult.new(@stream)])
64
+ mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>EXTERNAL</mechanism></mechanisms>}
65
+ node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
66
+ @state.node(node)
67
+ assert @stream.verify
68
+ end
69
+
70
+ private
71
+
72
+ def node(xml)
73
+ Nokogiri::XML(xml).root
74
+ end
75
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stream::Server::Outbound::AuthRestart do
6
+ before do
7
+ @stream = MiniTest::Mock.new
8
+ @state = Vines::Stream::Server::Outbound::AuthRestart.new(@stream)
9
+ end
10
+
11
+ def test_missing_namespace
12
+ node = node('<stream:stream/>')
13
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
14
+ assert @stream.verify
15
+ end
16
+
17
+ def test_invalid_namespace
18
+ node = node(%Q{<stream:stream xmlns="#{Vines::NAMESPACES[:stream]}"/>})
19
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
20
+ end
21
+
22
+ def test_valid_stream
23
+ node = node(%Q{<stream:stream xmlns='jabber:client' xmlns:stream='#{Vines::NAMESPACES[:stream]}' xml:lang='en' id='1234' from='host.com' version='1.0'>})
24
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::AuthExternal])
25
+ @stream.expect(:dialback_retry?, false)
26
+ @state.node(node)
27
+ assert @stream.verify
28
+ end
29
+
30
+ def test_valid_stream_restart
31
+ node = node(%Q{<stream:stream xmlns='jabber:client' xmlns:stream='#{Vines::NAMESPACES[:stream]}' xml:lang='en' id='1234' from='host.com' version='1.0'>})
32
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::Auth])
33
+ @stream.expect(:outbound_tls_required?, false)
34
+ @stream.expect(:dialback_retry?, true)
35
+ @state.node(node)
36
+ assert @stream.verify
37
+ end
38
+
39
+ def test_valid_stream_required_tls
40
+ node = node(%Q{<stream:stream xmlns='jabber:client' xmlns:stream='#{Vines::NAMESPACES[:stream]}' xml:lang='en' id='1234' from='host.com' version='1.0'>})
41
+ @stream.expect(:close_connection, nil)
42
+ @stream.expect(:outbound_tls_required?, true)
43
+ @stream.expect(:dialback_retry?, true)
44
+ @state.node(node)
45
+ assert @stream.verify
46
+ end
47
+
48
+ private
49
+
50
+ def node(xml)
51
+ Nokogiri::XML(xml).root
52
+ end
53
+ end
@@ -2,67 +2,83 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- describe Vines::Stream::Server::Outbound::Auth do
6
- before do
7
- @stream = MiniTest::Mock.new
8
- @state = Vines::Stream::Server::Outbound::Auth.new(@stream)
9
- end
10
-
11
- def test_invalid_element
12
- node = node('<message/>')
13
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
5
+ class OperatorWrapper
6
+ def <<(stream)
7
+ [stream]
14
8
  end
9
+ end
15
10
 
16
- def test_invalid_sasl_element
17
- node = node(%Q{<message xmlns="#{Vines::NAMESPACES[:sasl]}"/>})
18
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
19
- end
11
+ class StateWrapper
12
+ def dialback_secret=(secret); end
13
+ end
20
14
 
21
- def test_missing_namespace
22
- node = node('<stream:features/>')
23
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
15
+ module Vines
16
+ module Kit
17
+ def auth_token; "1234"; end
24
18
  end
19
+ end
25
20
 
26
- def test_invalid_namespace
27
- node = node('<stream:features xmlns="bogus"/>')
28
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
29
- end
21
+ module Boolean; end
22
+ class TrueClass; include Boolean; end
23
+ class FalseClass; include Boolean; end
24
+ class NilClass; include Boolean; end
30
25
 
31
- def test_missing_mechanisms
32
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams"/>})
33
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
26
+ describe Vines::Stream::Server::Outbound::Auth do
27
+ before do
28
+ @stream = MiniTest::Mock.new
29
+ @state = Vines::Stream::Server::Outbound::Auth.new(@stream)
34
30
  end
35
31
 
36
- def test_missing_mechanisms_namespace
37
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams"><mechanisms/></stream:features>})
32
+ def test_missing_children
33
+ node = node('<stream:features/>')
34
+ @stream.expect(:dialback_verify_key?, false)
35
+ @stream.expect(:outbound_tls_required, nil, [Boolean])
38
36
  assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
37
+ assert @stream.verify
39
38
  end
40
39
 
41
- def test_missing_mechanism
42
- mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>}
43
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
40
+ def test_invalid_children
41
+ node = node(%Q{<stream:features><message/></stream:features>})
42
+ @stream.expect(:dialback_verify_key?, false)
43
+ @stream.expect(:outbound_tls_required, nil, [Boolean])
44
44
  assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
45
+ assert @stream.verify
45
46
  end
46
47
 
47
- def test_missing_mechanism_text
48
- mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism></mechanism></mechanisms>}
49
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
50
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
48
+ def test_valid_stream_features
49
+ node = node(%Q{<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}"><starttls xmlns="#{Vines::NAMESPACES[:tls]}"><required/></starttls><dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>})
50
+ starttls = "<starttls xmlns='#{Vines::NAMESPACES[:tls]}'/>"
51
+ @stream.expect(:dialback_verify_key?, false)
52
+ @stream.expect(:outbound_tls_required, nil, [Boolean])
53
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::TLSResult])
54
+ @stream.expect(:write, nil, [starttls])
55
+ @state.node(node)
56
+ assert @stream.verify
51
57
  end
52
58
 
53
- def test_invalid_mechanism_text
54
- mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>BOGUS</mechanism></mechanisms>}
55
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
56
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
59
+ def test_dialback_feature_only
60
+ node = node(%Q{<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}"><dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>})
61
+ @stream.expect(:dialback_verify_key?, false)
62
+ @stream.expect(:router, OperatorWrapper.new)
63
+ @stream.expect(:domain, "local.host")
64
+ @stream.expect(:remote_domain, "remote.host")
65
+ @stream.expect(:domain, "local.host")
66
+ @stream.expect(:remote_domain, "remote.host")
67
+ @stream.expect(:id, "1234")
68
+ @stream.expect(:write, nil, [String])
69
+ @stream.expect(:outbound_tls_required, nil, [Boolean])
70
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::AuthDialbackResult])
71
+ @stream.expect(:state, StateWrapper.new)
72
+ @state.node(node)
73
+ assert @stream.verify
57
74
  end
58
75
 
59
- def test_valid_mechanism
60
- @stream.expect(:domain, 'wonderland.lit')
61
- expected = %Q{<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="EXTERNAL">d29uZGVybGFuZC5saXQ=</auth>}
62
- @stream.expect(:write, nil, [expected])
63
- @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::AuthResult.new(@stream)])
64
- mechanisms = %q{<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>EXTERNAL</mechanism></mechanisms>}
65
- node = node(%Q{<stream:features xmlns:stream="http://etherx.jabber.org/streams">#{mechanisms}</stream:features>})
76
+ def test_dialback_verify_key
77
+ node = node('<stream:stream/>')
78
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::Authoritative])
79
+ @stream.expect(:dialback_verify_key?, true)
80
+ @stream.expect(:callback!, nil)
81
+ @stream.expect(:outbound_tls_required, nil, [Boolean])
66
82
  @state.node(node)
67
83
  assert @stream.verify
68
84
  end
@@ -0,0 +1,66 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ class RouterWrapper
6
+ def initialize(stream); @stream = stream; end
7
+ def stream_by_id(id); @stream; end
8
+ end
9
+
10
+ describe Vines::Stream::Server::Outbound::Authoritative do
11
+ before do
12
+ @stream = MiniTest::Mock.new
13
+ @router = RouterWrapper.new(@stream)
14
+ @state = Vines::Stream::Server::Outbound::Authoritative.new(@stream)
15
+ end
16
+
17
+ def test_invalid_stanza
18
+ node = node('<message/>')
19
+ @stream.expect(:router, @router)
20
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
21
+ assert @stream.verify
22
+ end
23
+
24
+ def test_invalid_token
25
+ node = node('<db:verify/>')
26
+ router = RouterWrapper.new(nil)
27
+ @stream.expect(:router, router)
28
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
29
+ assert @stream.verify
30
+ end
31
+
32
+ def test_valid_verification
33
+ node = node(%Q{<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" id="1234" type="valid"/>})
34
+ result = "<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>"
35
+ @stream.expect(:router, @router)
36
+ # NOTE this tests the 'inbound' stream var
37
+ @stream.expect(:write, nil, [result])
38
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Ready])
39
+ @stream.expect(:notify_connected, nil)
40
+ # end
41
+ @stream.expect(:nil?, false)
42
+ @stream.expect(:close_connection, nil)
43
+ @state.node(node)
44
+ assert @stream.verify
45
+ end
46
+
47
+ def test_invalid_verification
48
+ node = node(%Q{<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" id="1234" type="invalid"/>})
49
+ result = "<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>"
50
+ @stream.expect(:router, @router)
51
+ # NOTE this tests the 'inbound' stream var
52
+ @stream.expect(:close_connection_after_writing, nil)
53
+ @stream.expect(:write, nil, [result])
54
+ # end
55
+ @stream.expect(:nil?, false)
56
+ @stream.expect(:close_connection, nil)
57
+ @state.node(node)
58
+ assert @stream.verify
59
+ end
60
+
61
+ private
62
+
63
+ def node(xml)
64
+ Nokogiri::XML(xml).root
65
+ end
66
+ end