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,186 +1,205 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class SubscribePubSubTest < 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::Subscribe do
6
+ subject { Vines::Stanza::PubSub::Subscribe.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
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
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.user = alice
28
+ stream.domain = 'wonderland.lit'
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
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
37
+ </pubsub>
38
+ </iq>
39
+ })
40
+ end
32
41
 
33
- stanza = Vines::Stanza::PubSub::Subscribe.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
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
43
- </pubsub>
44
- </iq>
45
- }.strip.gsub(/\n|\s{2,}/, ''))
46
-
47
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
48
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
49
- assert @stream.verify
50
- end
48
+ describe 'when addressed to a bare server domain' 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
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
54
+ </pubsub>
55
+ </iq>
56
+ })
57
+ end
51
58
 
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
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
57
- </pubsub>
58
- </iq>
59
- }.strip.gsub(/\n|\s{2,}/, ''))
59
+ it 'raises a feature-not-implemented stanza error' do
60
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
61
+ stream.verify
62
+ end
63
+ end
60
64
 
61
- router = MiniTest::Mock.new
62
- router.expect(:route, nil, [node])
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
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
72
+ </pubsub>
73
+ </iq>
74
+ })
75
+ end
63
76
 
64
- @stream.expect(:router, router)
77
+ it 'routes rather than handle locally' do
78
+ router.expect :route, nil, [xml]
79
+ stream.expect :router, router
65
80
 
66
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
67
- stanza.process
68
- assert @stream.verify
69
- assert router.verify
81
+ subject.process
82
+ stream.verify
83
+ router.verify
84
+ end
70
85
  end
71
86
 
72
- def test_multiple_subscribe_elements_raises
73
- node = node(%q{
74
- <iq type='set' to='games.wonderland.lit' id='42'>
75
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
76
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
77
- <subscribe node='game_14' jid="alice@wonderland.lit/tea"/>
78
- </pubsub>
79
- </iq>
80
- }.strip.gsub(/\n|\s{2,}/, ''))
81
-
82
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
83
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
84
- assert @stream.verify
87
+ describe 'when stanza contains multiple subscribe elements' do
88
+ let(:xml) do
89
+ node(%q{
90
+ <iq type='set' to='games.wonderland.lit' id='42'>
91
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
92
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
93
+ <subscribe node='game_14' jid="alice@wonderland.lit/tea"/>
94
+ </pubsub>
95
+ </iq>
96
+ })
97
+ end
98
+
99
+ it 'raises a bad-request stanza error' do
100
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
101
+ stream.verify
102
+ end
85
103
  end
86
104
 
87
- def test_subscribe_missing_node_raises
88
- node = node(%q{
89
- <iq type='set' to='games.wonderland.lit' id='42'>
90
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
91
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
92
- </pubsub>
93
- </iq>
94
- }.strip.gsub(/\n|\s{2,}/, ''))
95
-
96
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
97
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
98
- assert @stream.verify
105
+ describe 'when stanza is missing a subscribe element' do
106
+ let(:xml) do
107
+ node(%q{
108
+ <iq type='set' to='games.wonderland.lit' id='42'>
109
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
110
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
111
+ </pubsub>
112
+ </iq>
113
+ })
114
+ end
115
+
116
+ it 'raises an item-not-found stanza error' do
117
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
118
+ stream.verify
119
+ end
99
120
  end
100
121
 
101
- def test_subscribe_twice_raises
102
- node = node(%q{
103
- <iq type='set' to='games.wonderland.lit' id='42'>
104
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
105
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
106
- </pubsub>
107
- </iq>
108
- }.strip.gsub(/\n|\s{2,}/, ''))
109
-
110
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
111
- def stanza.mock_pubsub; @mock_pubsub; end
112
- def stanza.pubsub
113
- unless @mock_pubsub
114
- @mock_pubsub = MiniTest::Mock.new
115
- @mock_pubsub.expect(:node?, true, ['game_13'])
116
- @mock_pubsub.expect(:subscribed?, true, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
122
+ describe 'when attempting to subscribe to a node twice' do
123
+ let(:pubsub) { MiniTest::Mock.new }
124
+ let(:xml) do
125
+ node(%q{
126
+ <iq type='set' to='games.wonderland.lit' id='42'>
127
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
128
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
129
+ </pubsub>
130
+ </iq>
131
+ })
132
+ end
133
+
134
+ before do
135
+ pubsub.expect :node?, true, ['game_13']
136
+ pubsub.expect :subscribed?, true, ['game_13', alice.jid]
137
+ end
138
+
139
+ it 'raises a policy-violation stanza error' do
140
+ subject.stub :pubsub, pubsub do
141
+ -> { subject.process }.must_raise Vines::StanzaErrors::PolicyViolation
117
142
  end
118
- @mock_pubsub
143
+ stream.verify
144
+ pubsub.verify
119
145
  end
120
- assert_raises(Vines::StanzaErrors::PolicyViolation) { stanza.process }
121
- assert @stream.verify
122
- assert stanza.mock_pubsub.verify
123
146
  end
124
147
 
125
- def test_subscribe_illegal_jid_raises
126
- node = node(%q{
127
- <iq type='set' to='games.wonderland.lit' id='42'>
128
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
129
- <subscribe node='game_13' jid="not_alice@wonderland.lit/tea"/>
130
- </pubsub>
131
- </iq>
132
- }.strip.gsub(/\n|\s{2,}/, ''))
133
-
134
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
135
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
136
- assert @stream.verify
148
+ describe 'when subscribing with an illegal jid' do
149
+ let(:xml) do
150
+ node(%q{
151
+ <iq type='set' to='games.wonderland.lit' id='42'>
152
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
153
+ <subscribe node='game_13' jid="not_alice@wonderland.lit/tea"/>
154
+ </pubsub>
155
+ </iq>
156
+ })
157
+ end
158
+
159
+ it 'raises a bad-request stanza error' do
160
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
161
+ stream.verify
162
+ end
137
163
  end
138
164
 
139
- def test_good_stanza_processes
140
- node = node(%q{
141
- <iq type='set' to='games.wonderland.lit' id='42'>
142
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
143
- <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
144
- </pubsub>
145
- </iq>
146
- }.strip.gsub(/\n|\s{2,}/, ''))
147
-
148
- def @stream.nodes; @nodes; end
149
- def @stream.write(node)
150
- @nodes ||= []
151
- @nodes << node
152
- end
153
-
154
- stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream)
155
- def stanza.mock_pubsub; @mock_pubsub; end
156
- def stanza.pubsub
157
- unless @mock_pubsub
158
- @mock_pubsub = MiniTest::Mock.new
159
- @mock_pubsub.expect(:node?, true, ['game_13'])
160
- @mock_pubsub.expect(:subscribed?, false, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
161
- @mock_pubsub.expect(:subscribe, nil, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
162
- end
163
- @mock_pubsub
165
+ describe 'when subscribing with a valid stanza' do
166
+ let(:xml) do
167
+ node(%q{
168
+ <iq type='set' to='games.wonderland.lit' id='42'>
169
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
170
+ <subscribe node='game_13' jid="alice@wonderland.lit/tea"/>
171
+ </pubsub>
172
+ </iq>
173
+ })
164
174
  end
165
- stanza.process
166
175
 
167
- assert @stream.verify
168
- assert stanza.mock_pubsub.verify
169
- assert_equal 1, @stream.nodes.size
176
+ let(:expected) do
177
+ node(%q{
178
+ <iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
179
+ <pubsub xmlns="http://jabber.org/protocol/pubsub">
180
+ <subscription node="game_13" jid="alice@wonderland.lit/tea" subscription="subscribed"/>
181
+ </pubsub>
182
+ </iq>
183
+ })
184
+ end
170
185
 
171
- expected = node(%q{
172
- <iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
173
- <pubsub xmlns="http://jabber.org/protocol/pubsub">
174
- <subscription node="game_13" jid="alice@wonderland.lit/tea" subscription="subscribed"/>
175
- </pubsub>
176
- </iq>
177
- }.strip.gsub(/\n|\s{2,}/, ''))
178
- assert_equal expected, @stream.nodes[0]
179
- end
186
+ let(:pubsub) { MiniTest::Mock.new }
180
187
 
181
- private
188
+ before do
189
+ pubsub.expect :node?, true, ['game_13']
190
+ pubsub.expect :subscribed?, false, ['game_13', alice.jid]
191
+ pubsub.expect :subscribe, nil, ['game_13', alice.jid]
192
+ end
193
+
194
+ it 'writes a result stanza to the stream' do
195
+ subject.stub :pubsub, pubsub do
196
+ subject.process
197
+ end
182
198
 
183
- def node(xml)
184
- Nokogiri::XML(xml).root
199
+ stream.verify
200
+ pubsub.verify
201
+ stream.nodes.size.must_equal 1
202
+ stream.nodes.first.must_equal expected
203
+ end
185
204
  end
186
205
  end
@@ -1,179 +1,148 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class UnsubscribePubSubTest < 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::Unsubscribe do
6
+ subject { Vines::Stanza::PubSub::Unsubscribe.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
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
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) { unsubscribe('') }
32
32
 
33
- stanza = Vines::Stanza::PubSub::Unsubscribe.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
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
43
- </pubsub>
44
- </iq>
45
- }.strip.gsub(/\n|\s{2,}/, ''))
46
-
47
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
48
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
49
- assert @stream.verify
40
+ describe 'when addressed to bare server domain' do
41
+ let(:xml) { unsubscribe('wonderland.lit') }
42
+
43
+ it 'raises a feature-not-implemented stanza error' do
44
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
45
+ stream.verify
46
+ end
50
47
  end
51
48
 
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
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
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::Unsubscribe.new(node, @stream)
66
- stanza.process
67
- assert @stream.verify
68
- assert router.verify
49
+ describe 'when addressed to a non-pubsub component' do
50
+ let(:router) { MiniTest::Mock.new }
51
+ let(:xml) { unsubscribe('bogus.wonderland.lit') }
52
+
53
+ before do
54
+ router.expect :route, nil, [xml]
55
+ stream.expect :router, router
56
+ end
57
+
58
+ it 'routes rather than handle locally' do
59
+ subject.process
60
+ stream.verify
61
+ router.verify
62
+ end
69
63
  end
70
64
 
71
- def test_multiple_unsubscribe_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
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
76
- <unsubscribe node='game_14' jid="alice@wonderland.lit/tea"/>
77
- </pubsub>
78
- </iq>
79
- }.strip.gsub(/\n|\s{2,}/, ''))
80
-
81
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
82
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
83
- assert @stream.verify
65
+ describe 'when attempting to unsubscribe from multiple nodes' do
66
+ let(:xml) { unsubscribe('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
71
+ end
84
72
  end
85
73
 
86
- def test_unsubscribe_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
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
91
- </pubsub>
92
- </iq>
93
- }.strip.gsub(/\n|\s{2,}/, ''))
94
-
95
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
96
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
97
- assert @stream.verify
74
+ describe 'when unsubscribing from a missing node' do
75
+ let(:xml) { unsubscribe('games.wonderland.lit') }
76
+
77
+ it 'raises an item-not-found stanza error' do
78
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
79
+ stream.verify
80
+ end
98
81
  end
99
82
 
100
- def test_unsubscribe_without_subscription_raises
101
- node = node(%q{
102
- <iq type='set' to='games.wonderland.lit' id='42'>
103
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
104
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
105
- </pubsub>
106
- </iq>
107
- }.strip.gsub(/\n|\s{2,}/, ''))
108
-
109
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
110
- def stanza.mock_pubsub; @mock_pubsub; end
111
- def stanza.pubsub
112
- unless @mock_pubsub
113
- @mock_pubsub = MiniTest::Mock.new
114
- @mock_pubsub.expect(:node?, true, ['game_13'])
115
- @mock_pubsub.expect(:subscribed?, false, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
83
+ describe 'when unsubscribing without a subscription' do
84
+ let(:pubsub) { MiniTest::Mock.new }
85
+ let(:xml) { unsubscribe('games.wonderland.lit') }
86
+
87
+ before do
88
+ pubsub.expect :node?, true, ['game_13']
89
+ pubsub.expect :subscribed?, false, ['game_13', user.jid]
90
+ end
91
+
92
+ it 'raises an unexpected-request stanza error' do
93
+ subject.stub :pubsub, pubsub do
94
+ -> { subject.process }.must_raise Vines::StanzaErrors::UnexpectedRequest
116
95
  end
117
- @mock_pubsub
96
+ stream.verify
97
+ pubsub.verify
118
98
  end
119
- assert_raises(Vines::StanzaErrors::UnexpectedRequest) { stanza.process }
120
- assert @stream.verify
121
- assert stanza.mock_pubsub.verify
122
99
  end
123
100
 
124
- def test_unsubscribe_illegal_jid_raises
125
- node = node(%q{
126
- <iq type='set' to='games.wonderland.lit' id='42'>
127
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
128
- <unsubscribe node='game_13' jid="not_alice@wonderland.lit/tea"/>
129
- </pubsub>
130
- </iq>
131
- }.strip.gsub(/\n|\s{2,}/, ''))
132
-
133
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
134
- assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process }
135
- assert @stream.verify
136
- end
101
+ describe 'when unsubscribing an illegal jid' do
102
+ let(:xml) { unsubscribe('games.wonderland.lit', false, 'not_alice@wonderland.lit/tea') }
137
103
 
138
- def test_good_stanza_processes
139
- node = node(%q{
140
- <iq type='set' to='games.wonderland.lit' id='42'>
141
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
142
- <unsubscribe node='game_13' jid="alice@wonderland.lit/tea"/>
143
- </pubsub>
144
- </iq>
145
- }.strip.gsub(/\n|\s{2,}/, ''))
146
-
147
- def @stream.nodes; @nodes; end
148
- def @stream.write(node)
149
- @nodes ||= []
150
- @nodes << node
104
+ it 'raises a forbidden stanza error' do
105
+ -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden
106
+ stream.verify
151
107
  end
108
+ end
152
109
 
153
- stanza = Vines::Stanza::PubSub::Unsubscribe.new(node, @stream)
154
- def stanza.mock_pubsub; @mock_pubsub; end
155
- def stanza.pubsub
156
- unless @mock_pubsub
157
- @mock_pubsub = MiniTest::Mock.new
158
- @mock_pubsub.expect(:node?, true, ['game_13'])
159
- @mock_pubsub.expect(:subscribed?, true, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
160
- @mock_pubsub.expect(:unsubscribe, nil, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')])
161
- end
162
- @mock_pubsub
110
+ describe 'when given a valid stanza' do
111
+ let(:pubsub) { MiniTest::Mock.new }
112
+ let(:xml) { unsubscribe('games.wonderland.lit') }
113
+ let(:expected) { result(user.jid, 'games.wonderland.lit') }
114
+
115
+ before do
116
+ pubsub.expect :node?, true, ['game_13']
117
+ pubsub.expect :subscribed?, true, ['game_13', user.jid]
118
+ pubsub.expect :unsubscribe, nil, ['game_13', user.jid]
163
119
  end
164
- stanza.process
165
120
 
166
- assert @stream.verify
167
- assert stanza.mock_pubsub.verify
168
- assert_equal 1, @stream.nodes.size
121
+ it 'sends an iq result stanza to sender' do
122
+ subject.stub :pubsub, pubsub do
123
+ subject.process
124
+ end
169
125
 
170
- expected = node(%q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
171
- assert_equal expected, @stream.nodes[0]
126
+ stream.nodes.size.must_equal 1
127
+ stream.nodes.first.must_equal expected
128
+ stream.verify
129
+ pubsub.verify
130
+ end
172
131
  end
173
132
 
174
133
  private
175
134
 
176
- def node(xml)
177
- Nokogiri::XML(xml).root
135
+ def unsubscribe(to, multiple=false, jid=user.jid)
136
+ extra = "<unsubscribe node='game_14' jid='#{jid}'/>" if multiple
137
+ body = %Q{
138
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
139
+ <unsubscribe node='game_13' jid="#{jid}"/>
140
+ #{extra}
141
+ </pubsub>}
142
+ iq(type: 'set', to: to, id: 42, body: body)
143
+ end
144
+
145
+ def result(to, from)
146
+ iq(from: from, id: 42, to: to, type: 'result')
178
147
  end
179
148
  end