vines 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +48 -0
  3. data/Rakefile +6 -58
  4. data/bin/vines +12 -2
  5. data/conf/certs/ca-bundle.crt +568 -39
  6. data/conf/config.rb +9 -42
  7. data/lib/vines.rb +1 -8
  8. data/lib/vines/command/cert.rb +4 -4
  9. data/lib/vines/command/init.rb +3 -3
  10. data/lib/vines/config.rb +9 -0
  11. data/lib/vines/kit.rb +2 -7
  12. data/lib/vines/storage/local.rb +50 -17
  13. data/lib/vines/store.rb +6 -4
  14. data/lib/vines/stream.rb +1 -1
  15. data/lib/vines/stream/http/session.rb +0 -0
  16. data/lib/vines/stream/http/sessions.rb +0 -0
  17. data/lib/vines/stream/parser.rb +3 -2
  18. data/lib/vines/token_bucket.rb +19 -10
  19. data/lib/vines/version.rb +1 -1
  20. data/test/cluster/publisher_test.rb +45 -33
  21. data/test/cluster/sessions_test.rb +32 -39
  22. data/test/cluster/subscriber_test.rb +93 -78
  23. data/test/config/host_test.rb +2 -4
  24. data/test/config/pubsub_test.rb +132 -126
  25. data/test/config_test.rb +2 -4
  26. data/test/contact_test.rb +80 -66
  27. data/test/error_test.rb +54 -55
  28. data/test/jid_test.rb +1 -2
  29. data/test/kit_test.rb +22 -17
  30. data/test/router_test.rb +187 -146
  31. data/test/stanza/iq/disco_info_test.rb +59 -59
  32. data/test/stanza/iq/disco_items_test.rb +36 -34
  33. data/test/stanza/iq/private_storage_test.rb +138 -143
  34. data/test/stanza/iq/roster_test.rb +198 -175
  35. data/test/stanza/iq/session_test.rb +17 -18
  36. data/test/stanza/iq/vcard_test.rb +117 -116
  37. data/test/stanza/iq/version_test.rb +47 -46
  38. data/test/stanza/iq_test.rb +53 -49
  39. data/test/stanza/message_test.rb +92 -89
  40. data/test/stanza/presence/probe_test.rb +2 -5
  41. data/test/stanza/presence/subscribe_test.rb +67 -54
  42. data/test/stanza/pubsub/create_test.rb +86 -108
  43. data/test/stanza/pubsub/delete_test.rb +141 -114
  44. data/test/stanza/pubsub/publish_test.rb +256 -320
  45. data/test/stanza/pubsub/subscribe_test.rb +169 -150
  46. data/test/stanza/pubsub/unsubscribe_test.rb +111 -142
  47. data/test/stanza_test.rb +61 -54
  48. data/test/storage/ldap_test.rb +1 -2
  49. data/test/storage/local_test.rb +3 -5
  50. data/test/storage/null_test.rb +3 -4
  51. data/test/storage/storage_tests.rb +1 -3
  52. data/test/storage_test.rb +1 -2
  53. data/test/store_test.rb +1 -2
  54. data/test/stream/client/auth_test.rb +61 -63
  55. data/test/stream/client/ready_test.rb +7 -8
  56. data/test/stream/client/session_test.rb +19 -18
  57. data/test/stream/component/handshake_test.rb +40 -37
  58. data/test/stream/component/ready_test.rb +76 -61
  59. data/test/stream/component/start_test.rb +7 -8
  60. data/test/stream/http/auth_test.rb +3 -4
  61. data/test/stream/http/ready_test.rb +52 -60
  62. data/test/stream/http/request_test.rb +1 -3
  63. data/test/stream/http/sessions_test.rb +2 -3
  64. data/test/stream/http/start_test.rb +3 -4
  65. data/test/stream/parser_test.rb +3 -4
  66. data/test/stream/sasl_test.rb +105 -86
  67. data/test/stream/server/auth_test.rb +40 -36
  68. data/test/stream/server/outbound/auth_test.rb +3 -4
  69. data/test/stream/server/ready_test.rb +51 -51
  70. data/test/test_helper.rb +42 -0
  71. data/test/token_bucket_test.rb +38 -18
  72. data/test/user_test.rb +79 -49
  73. data/vines.gemspec +33 -0
  74. data/web/chat/javascripts/app.js +1 -1
  75. data/web/lib/coffeescripts/layout.coffee +1 -1
  76. data/web/lib/javascripts/base.js +10 -10
  77. data/web/lib/javascripts/jquery.js +4 -4
  78. metadata +31 -128
  79. data/README +0 -35
  80. data/lib/vines/storage/couchdb.rb +0 -129
  81. data/lib/vines/storage/mongodb.rb +0 -132
  82. data/lib/vines/storage/redis.rb +0 -127
  83. data/lib/vines/storage/sql.rb +0 -220
  84. data/test/rake_test_loader.rb +0 -17
  85. data/test/storage/couchdb_test.rb +0 -107
  86. data/test/storage/mock_mongo.rb +0 -40
  87. data/test/storage/mongodb_test.rb +0 -81
  88. data/test/storage/redis_test.rb +0 -51
  89. data/test/storage/sql_test.rb +0 -62
@@ -1,70 +1,83 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'vines'
4
- require 'ext/nokogiri'
5
- require 'minitest/autorun'
3
+ require 'test_helper'
6
4
 
7
- class SubscribeTest < MiniTest::Unit::TestCase
8
- def test_outbound_subscribe_to_local_jid_but_missing_contact
9
- alice = Vines::JID.new('alice@wonderland.lit/tea')
10
- hatter = Vines::JID.new('hatter@wonderland.lit')
5
+ describe Vines::Stanza::Presence::Subscribe do
6
+ subject { Vines::Stanza::Presence::Subscribe.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::JID.new('alice@wonderland.lit/tea') }
9
+ let(:hatter) { Vines::JID.new('hatter@wonderland.lit') }
10
+ let(:contact) { Vines::Contact.new(jid: hatter) }
11
11
 
12
- contact = Vines::Contact.new(:jid => hatter)
12
+ before do
13
+ class << stream
14
+ attr_accessor :user, :nodes
15
+ def write(node)
16
+ @nodes ||= []
17
+ @nodes << node
18
+ end
19
+ end
20
+ end
13
21
 
14
- user = MiniTest::Mock.new
15
- user.expect(:jid, alice)
16
- user.expect(:request_subscription, nil, [hatter])
17
- user.expect(:contact, contact, [hatter])
22
+ describe 'outbound subscription to a local jid, but missing contact' do
23
+ let(:xml) { node(%q{<presence id="42" to="hatter@wonderland.lit" type="subscribe"/>}) }
24
+ let(:user) { MiniTest::Mock.new }
25
+ let(:storage) { MiniTest::Mock.new }
26
+ let(:recipient) { MiniTest::Mock.new }
18
27
 
19
- storage = MiniTest::Mock.new
20
- storage.expect(:save_user, nil, [user])
21
- storage.expect(:find_user, nil, [hatter])
28
+ before do
29
+ class << user
30
+ attr_accessor :jid
31
+ end
32
+ user.jid = alice
33
+ user.expect :request_subscription, nil, [hatter]
34
+ user.expect :contact, contact, [hatter]
22
35
 
23
- recipient = MiniTest::Mock.new
24
- recipient.expect(:user, user)
25
- def recipient.nodes; @nodes; end
26
- def recipient.write(node)
27
- @nodes ||= []
28
- @nodes << node
29
- end
36
+ storage.expect :save_user, nil, [user]
37
+ storage.expect :find_user, nil, [hatter]
30
38
 
31
- stream = MiniTest::Mock.new
32
- stream.expect(:domain, 'wonderland.lit')
33
- stream.expect(:storage, storage, ['wonderland.lit'])
34
- stream.expect(:user, user)
35
- stream.expect(:interested_resources, [recipient], [alice])
36
- stream.expect(:update_user_streams, nil, [user])
37
- def stream.nodes; @nodes; end
38
- def stream.write(node)
39
- @nodes ||= []
40
- @nodes << node
41
- end
39
+ recipient.expect :user, user
40
+ class << recipient
41
+ attr_accessor :nodes
42
+ def write(node)
43
+ @nodes ||= []
44
+ @nodes << node
45
+ end
46
+ end
42
47
 
43
- node = node(%q{<presence id="42" to="hatter@wonderland.lit" type="subscribe"/>})
44
- stanza = Vines::Stanza::Presence::Subscribe.new(node, stream)
45
- def stanza.route_iq; false; end
46
- def stanza.inbound?; false; end
47
- def stanza.local?; true; end
48
+ stream.user = user
49
+ stream.expect :domain, 'wonderland.lit'
50
+ stream.expect :storage, storage, ['wonderland.lit']
51
+ stream.expect :storage, storage, ['wonderland.lit']
52
+ stream.expect :interested_resources, [recipient], [alice]
53
+ stream.expect :update_user_streams, nil, [user]
48
54
 
49
- stanza.process
50
- assert stream.verify
51
- assert user.verify
52
- assert storage.verify
53
- assert_equal 1, stream.nodes.size
54
- assert_equal 1, recipient.nodes.size
55
+ class << subject
56
+ def route_iq; false; end
57
+ def inbound?; false; end
58
+ def local?; true; end
59
+ end
60
+ end
55
61
 
56
- expected = node(%q{<presence from="hatter@wonderland.lit" id="42" to="alice@wonderland.lit" type="unsubscribed"/>})
57
- assert_equal expected, stream.nodes[0]
62
+ it 'rejects the subscription with an unsubscribed response' do
63
+ subject.process
64
+ stream.verify
65
+ user.verify
66
+ storage.verify
67
+ stream.nodes.size.must_equal 1
58
68
 
59
- query = %q{<query xmlns="jabber:iq:roster"><item jid="hatter@wonderland.lit" subscription="none"/></query>}
60
- expected = node(%Q{<iq to="alice@wonderland.lit/tea" type="set">#{query}</iq>})
61
- recipient.nodes[0].remove_attribute('id') # id is random
62
- assert_equal expected, recipient.nodes[0]
63
- end
69
+ expected = node(%q{<presence from="hatter@wonderland.lit" id="42" to="alice@wonderland.lit" type="unsubscribed"/>})
70
+ stream.nodes.first.must_equal expected
71
+ end
64
72
 
65
- private
73
+ it 'sends a roster set to the interested resources with subscription none' do
74
+ subject.process
75
+ recipient.nodes.size.must_equal 1
66
76
 
67
- def node(xml)
68
- Nokogiri::XML(xml).root
77
+ query = %q{<query xmlns="jabber:iq:roster"><item jid="hatter@wonderland.lit" subscription="none"/></query>}
78
+ expected = node(%Q{<iq to="alice@wonderland.lit/tea" type="set">#{query}</iq>})
79
+ recipient.nodes.first.remove_attribute('id') # id is random
80
+ recipient.nodes.first.must_equal expected
81
+ end
69
82
  end
70
83
  end
@@ -1,138 +1,116 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class CreatePubSubTest < MiniTest::Unit::TestCase
9
- def setup
10
- @user = Vines::User.new(jid: 'alice@wonderland.lit/tea')
11
- @config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::PubSub::Create do
6
+ subject { Vines::Stanza::PubSub::Create.new(xml, stream) }
7
+ let(:user) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
8
+ let(:stream) { MiniTest::Mock.new }
9
+ let(:config) do
10
+ Vines::Config.new do
12
11
  host 'wonderland.lit' do
13
12
  storage(:fs) { dir Dir.tmpdir }
14
13
  pubsub 'games'
15
14
  end
16
15
  end
17
- @stream = MiniTest::Mock.new
18
- @stream.expect(:config, @config)
19
- @stream.expect(:user, @user)
20
16
  end
21
17
 
22
- def test_missing_to_address_raises
23
- node = node(%q{
24
- <iq type='set' id='42'>
25
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
26
- <create node='game_13'/>
27
- </pubsub>
28
- </iq>
29
- }.strip.gsub(/\n|\s{2,}/, ''))
18
+ before do
19
+ class << stream
20
+ attr_accessor :config, :nodes, :user
21
+ def write(node)
22
+ @nodes ||= []
23
+ @nodes << node
24
+ end
25
+ end
26
+ stream.config = config
27
+ stream.user = user
28
+ end
30
29
 
31
- @stream.expect(:domain, 'wonderland.lit')
30
+ describe 'when missing a to address' do
31
+ let(:xml) { create('') }
32
32
 
33
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
34
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
35
- assert @stream.verify
33
+ it 'raises a feature-not-implemented stanza error' do
34
+ stream.expect :domain, 'wonderland.lit'
35
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
36
+ stream.verify
37
+ end
36
38
  end
37
39
 
38
- def test_server_domain_to_address_raises
39
- node = node(%q{
40
- <iq type='set' to='wonderland.lit' id='42'>
41
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
42
- <create node='game_13'/>
43
- </pubsub>
44
- </iq>
45
- }.strip.gsub(/\n|\s{2,}/, ''))
46
-
47
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
48
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
49
- assert @stream.verify
50
- end
40
+ describe 'when addressed to bare server domain' do
41
+ let(:xml) { create('wonderland.lit') }
51
42
 
52
- def test_non_pubsub_to_address_routes
53
- node = node(%q{
54
- <iq type='set' to='bogus.wonderland.lit' id='42'>
55
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
56
- <create node='game_13'/>
57
- </pubsub>
58
- </iq>
59
- }.strip.gsub(/\n|\s{2,}/, ''))
60
-
61
- router = MiniTest::Mock.new
62
- router.expect(:route, nil, [node])
63
- @stream.expect(:router, router)
64
-
65
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
66
- stanza.process
67
- assert @stream.verify
68
- assert router.verify
43
+ it 'raises a feature-not-implemented stanza error' do
44
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
45
+ stream.verify
46
+ end
69
47
  end
70
48
 
71
- def test_multiple_create_elements_raises
72
- node = node(%q{
73
- <iq type='set' to='games.wonderland.lit' id='42'>
74
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
75
- <create node='game_13'/>
76
- <create node='game_14'/>
77
- </pubsub>
78
- </iq>
79
- }.strip.gsub(/\n|\s{2,}/, ''))
80
-
81
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
82
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
83
- assert @stream.verify
84
- end
49
+ describe 'when addressed to a non-pubsub component' do
50
+ let(:router) { MiniTest::Mock.new }
51
+ let(:xml) { create('bogus.wonderland.lit') }
52
+
53
+ before do
54
+ router.expect :route, nil, [xml]
55
+ stream.expect :router, router
56
+ end
85
57
 
86
- def test_create_duplicate_node_raises
87
- node = node(%q{
88
- <iq type='set' to='games.wonderland.lit' id='42'>
89
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
90
- <create node='game_13'/>
91
- </pubsub>
92
- </iq>
93
- }.strip.gsub(/\n|\s{2,}/, ''))
94
-
95
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
96
- def stanza.pubsub
97
- pubsub = MiniTest::Mock.new
98
- pubsub.expect(:node?, true, ['game_13'])
99
- pubsub
58
+ it 'routes rather than handle locally' do
59
+ subject.process
60
+ stream.verify
61
+ router.verify
100
62
  end
101
- assert_raises(Vines::StanzaErrors::Conflict) { stanza.process }
102
- assert @stream.verify
103
63
  end
104
64
 
105
- def test_good_stanza_processes
106
- node = node(%q{
107
- <iq type='set' to='games.wonderland.lit' id='42'>
108
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
109
- <create node='game_13'/>
110
- </pubsub>
111
- </iq>
112
- }.strip.gsub(/\n|\s{2,}/, ''))
113
-
114
- def @stream.nodes; @nodes; end
115
- def @stream.write(node)
116
- @nodes ||= []
117
- @nodes << node
65
+ describe 'when attempting to create multiple nodes' do
66
+ let(:xml) { create('games.wonderland.lit', true) }
67
+
68
+ it 'raises a bad-request stanza error' do
69
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
70
+ stream.verify
118
71
  end
72
+ end
119
73
 
120
- stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
121
- stanza.process
74
+ describe 'when attempting to create duplicate nodes' do
75
+ let(:pubsub) { MiniTest::Mock.new }
76
+ let(:xml) { create('games.wonderland.lit') }
122
77
 
123
- assert @stream.verify
124
- assert_equal 1, @stream.nodes.size
78
+ it 'raises a conflict stanza error' do
79
+ pubsub.expect :node?, true, ['game_13']
80
+ subject.stub :pubsub, pubsub do
81
+ -> { subject.process }.must_raise Vines::StanzaErrors::Conflict
82
+ end
83
+ stream.verify
84
+ pubsub.verify
85
+ end
86
+ end
125
87
 
126
- expected = %q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">}
127
- expected << %q{<pubsub xmlns="http://jabber.org/protocol/pubsub"><create node="game_13"/></pubsub>}
128
- expected << %q{</iq>}
129
- expected = node(expected)
130
- assert_equal expected, @stream.nodes[0]
88
+ describe 'when given a valid stanza' do
89
+ let(:xml) { create('games.wonderland.lit') }
90
+ let(:expected) { result(user.jid, 'games.wonderland.lit') }
91
+
92
+ it 'sends an iq result stanza to sender' do
93
+ subject.process
94
+ stream.nodes.size.must_equal 1
95
+ stream.nodes.first.must_equal expected
96
+ stream.verify
97
+ end
131
98
  end
132
99
 
133
100
  private
134
101
 
135
- def node(xml)
136
- Nokogiri::XML(xml).root
102
+ def create(to, multiple=false)
103
+ extra_create = "<create node='game_14'/>" if multiple
104
+ body = %Q{
105
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
106
+ <create node='game_13'/>
107
+ #{extra_create}
108
+ </pubsub>}
109
+ iq(type: 'set', to: to, id: 42, body: body)
110
+ end
111
+
112
+ def result(to, from)
113
+ body = '<pubsub xmlns="http://jabber.org/protocol/pubsub"><create node="game_13"/></pubsub>'
114
+ iq(from: from, id: 42, to: to, type: 'result', body: body)
137
115
  end
138
116
  end
@@ -1,142 +1,169 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class DeletePubSubTest < MiniTest::Unit::TestCase
9
- def setup
10
- @user = Vines::User.new(jid: 'alice@wonderland.lit/tea')
11
- @config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::PubSub::Delete do
6
+ subject { Vines::Stanza::PubSub::Delete.new(xml, stream) }
7
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
8
+ let(:stream) { MiniTest::Mock.new }
9
+ let(:config) do
10
+ Vines::Config.new do
12
11
  host 'wonderland.lit' do
13
12
  storage(:fs) { dir Dir.tmpdir }
14
13
  pubsub 'games'
15
14
  end
16
15
  end
17
- @stream = MiniTest::Mock.new
18
- @stream.expect(:config, @config)
19
- @stream.expect(:user, @user)
20
16
  end
21
17
 
22
- def test_missing_to_address_raises
23
- node = node(%q{
24
- <iq type='set' id='42'>
25
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
26
- <delete node='game_13'/>
27
- </pubsub>
28
- </iq>
29
- }.strip.gsub(/\n|\s{2,}/, ''))
18
+ before do
19
+ class << stream
20
+ attr_accessor :config, :domain, :nodes, :user
21
+ def write(node)
22
+ @nodes ||= []
23
+ @nodes << node
24
+ end
25
+ end
26
+ stream.config = config
27
+ stream.domain = 'wonderland.lit'
28
+ stream.user = alice
29
+ end
30
30
 
31
- @stream.expect(:domain, 'wonderland.lit')
31
+ describe 'when missing a to address' do
32
+ let(:xml) do
33
+ node(%q{
34
+ <iq type='set' id='42'>
35
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
36
+ <delete node='game_13'/>
37
+ </pubsub>
38
+ </iq>
39
+ })
40
+ end
32
41
 
33
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
34
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
35
- assert @stream.verify
42
+ it 'raises a feature-not-implemented stanza error' do
43
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
44
+ stream.verify
45
+ end
36
46
  end
37
47
 
38
- def test_server_domain_to_address_raises
39
- node = node(%q{
40
- <iq type='set' to='wonderland.lit' id='42'>
41
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
42
- <delete node='game_13'/>
43
- </pubsub>
44
- </iq>
45
- }.strip.gsub(/\n|\s{2,}/, ''))
46
-
47
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
48
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
49
- assert @stream.verify
48
+ describe 'when addressed to a bare server domain jid' do
49
+ let(:xml) do
50
+ node(%q{
51
+ <iq type='set' to='wonderland.lit' id='42'>
52
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
53
+ <delete node='game_13'/>
54
+ </pubsub>
55
+ </iq>
56
+ })
57
+ end
58
+
59
+ it 'raises a feature-not-implemented stanza error' do
60
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
61
+ stream.verify
62
+ end
50
63
  end
51
64
 
52
- def test_non_pubsub_to_address_routes
53
- node = node(%q{
54
- <iq type='set' to='bogus.wonderland.lit' id='42'>
55
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
56
- <delete node='game_13'/>
57
- </pubsub>
58
- </iq>
59
- }.strip.gsub(/\n|\s{2,}/, ''))
60
-
61
- router = MiniTest::Mock.new
62
- router.expect(:route, nil, [node])
63
- @stream.expect(:router, router)
64
-
65
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
66
- stanza.process
67
- assert @stream.verify
68
- assert router.verify
65
+ describe 'when addressed to a non-pubsub address' do
66
+ let(:router) { MiniTest::Mock.new }
67
+ let(:xml) do
68
+ node(%q{
69
+ <iq type='set' to='bogus.wonderland.lit' id='42'>
70
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
71
+ <delete node='game_13'/>
72
+ </pubsub>
73
+ </iq>
74
+ })
75
+ end
76
+
77
+ before do
78
+ router.expect :route, nil, [xml]
79
+ stream.expect :router, router
80
+ end
81
+
82
+ it 'routes rather than handle locally' do
83
+ subject.process
84
+ stream.verify
85
+ router.verify
86
+ end
69
87
  end
70
88
 
71
- def test_multiple_delete_elements_raises
72
- node = node(%q{
73
- <iq type='set' to='games.wonderland.lit' id='42'>
74
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
75
- <delete node='game_13'/>
76
- <delete node='game_14'/>
77
- </pubsub>
78
- </iq>
79
- }.strip.gsub(/\n|\s{2,}/, ''))
80
-
81
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
82
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
83
- assert @stream.verify
89
+ describe 'when stanza contains multiple delete elements' do
90
+ let(:xml) do
91
+ node(%q{
92
+ <iq type='set' to='games.wonderland.lit' id='42'>
93
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
94
+ <delete node='game_13'/>
95
+ <delete node='game_14'/>
96
+ </pubsub>
97
+ </iq>
98
+ })
99
+ end
100
+
101
+ it 'raises a bad-request stanza error' do
102
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
103
+ stream.verify
104
+ end
84
105
  end
85
106
 
86
- def test_delete_missing_node_raises
87
- node = node(%q{
88
- <iq type='set' to='games.wonderland.lit' id='42'>
89
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
90
- <delete node='game_13'/>
91
- </pubsub>
92
- </iq>
93
- }.strip.gsub(/\n|\s{2,}/, ''))
94
-
95
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
96
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
97
- assert @stream.verify
107
+ describe 'when deleting a missing node' do
108
+ let(:xml) do
109
+ node(%q{
110
+ <iq type='set' to='games.wonderland.lit' id='42'>
111
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
112
+ <delete node='game_13'/>
113
+ </pubsub>
114
+ </iq>
115
+ })
116
+ end
117
+
118
+ it 'raises an item-not-found stanza error' do
119
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
120
+ stream.verify
121
+ end
98
122
  end
99
123
 
100
- def test_good_stanza_processes
101
- node = node(%q{
102
- <iq type='set' to='games.wonderland.lit' id='42'>
103
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
104
- <delete node='game_13'/>
105
- </pubsub>
106
- </iq>
107
- }.strip.gsub(/\n|\s{2,}/, ''))
108
-
109
- def @stream.nodes; @nodes; end
110
- def @stream.write(node)
111
- @nodes ||= []
112
- @nodes << node
113
- end
114
-
115
- stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
116
- def stanza.mock_pubsub; @mock_pubsub; end
117
- def stanza.pubsub
118
- unless @mock_pubsub
119
- xml = %q{<message><event xmlns="http://jabber.org/protocol/pubsub#event"><delete node="game_13"/></event></message>}
120
- @mock_pubsub = MiniTest::Mock.new
121
- @mock_pubsub.expect(:node?, true, ['game_13'])
122
- @mock_pubsub.expect(:publish, nil, ['game_13', Nokogiri::XML(xml).root])
123
- @mock_pubsub.expect(:delete_node, nil, ['game_13'])
124
- end
125
- @mock_pubsub
124
+ describe 'when valid stanza is received' do
125
+ let(:pubsub) { MiniTest::Mock.new }
126
+ let(:xml) do
127
+ node(%q{
128
+ <iq type='set' to='games.wonderland.lit' id='42'>
129
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
130
+ <delete node='game_13'/>
131
+ </pubsub>
132
+ </iq>
133
+ })
126
134
  end
127
- stanza.process
128
135
 
129
- assert @stream.verify
130
- assert stanza.mock_pubsub.verify
131
- assert_equal 1, @stream.nodes.size
136
+ let(:result) { node(%Q{<iq from="games.wonderland.lit" id="42" to="#{alice.jid}" type="result"/>}) }
132
137
 
133
- expected = node(%q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
134
- assert_equal expected, @stream.nodes[0]
135
- end
138
+ let(:broadcast) do
139
+ node(%q{
140
+ <message>
141
+ <event xmlns="http://jabber.org/protocol/pubsub#event">
142
+ <delete node="game_13"/>
143
+ </event>
144
+ </message>})
145
+ end
136
146
 
137
- private
147
+ before do
148
+ pubsub.expect :node?, true, ['game_13']
149
+ pubsub.expect :publish, nil, ['game_13', broadcast]
150
+ pubsub.expect :delete_node, nil, ['game_13']
151
+ end
138
152
 
139
- def node(xml)
140
- Nokogiri::XML(xml).root
153
+ it 'broadcasts the delete to subscribers' do
154
+ subject.stub :pubsub, pubsub do
155
+ subject.process
156
+ end
157
+ stream.verify
158
+ pubsub.verify
159
+ end
160
+
161
+ it 'sends a result stanza to sender' do
162
+ subject.stub :pubsub, pubsub do
163
+ subject.process
164
+ end
165
+ stream.nodes.size.must_equal 1
166
+ stream.nodes.first.must_equal result
167
+ end
141
168
  end
142
169
  end