vines 0.4.5 → 0.4.6

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 (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,373 +1,309 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class PublishPubSubTest < 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::Publish do
6
+ subject { Vines::Stanza::PubSub::Publish.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
- <publish node='game_13'>
27
- <item id='item_42'>
28
- <entry xmlns='http://www.w3.org/2005/Atom'>
29
- <title>Test</title>
30
- <summary>This is a summary.</summary>
31
- </entry>
32
- </item>
33
- </publish>
34
- </pubsub>
35
- </iq>
36
- }.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
37
29
 
38
- @stream.expect(:domain, 'wonderland.lit')
30
+ describe 'when missing a to address' do
31
+ let(:xml) { publish('') }
39
32
 
40
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
41
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
42
- 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
43
38
  end
44
39
 
45
- def test_server_domain_to_address_raises
46
- node = node(%q{
47
- <iq type='set' to='wonderland.lit' id='42'>
48
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
49
- <publish node='game_13'>
50
- <item id='item_42'>
51
- <entry xmlns='http://www.w3.org/2005/Atom'>
52
- <title>Test</title>
53
- <summary>This is a summary.</summary>
54
- </entry>
55
- </item>
56
- </publish>
57
- </pubsub>
58
- </iq>
59
- }.strip.gsub(/\n|\s{2,}/, ''))
60
-
61
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
62
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
63
- assert @stream.verify
40
+ describe 'when addressed to bare server domain' do
41
+ let(:xml) { publish('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
64
47
  end
65
48
 
66
- def test_non_pubsub_to_address_routes
67
- node = node(%q{
68
- <iq type='set' to='bogus.wonderland.lit' id='42'>
69
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
70
- <publish node='game_13'>
71
- <item id='item_42'>
72
- <entry xmlns='http://www.w3.org/2005/Atom'>
73
- <title>Test</title>
74
- <summary>This is a summary.</summary>
75
- </entry>
76
- </item>
77
- </publish>
78
- </pubsub>
79
- </iq>
80
- }.strip.gsub(/\n|\s{2,}/, ''))
81
-
82
- router = MiniTest::Mock.new
83
- router.expect(:route, nil, [node])
84
- @stream.expect(:router, router)
85
-
86
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
87
- stanza.process
88
- assert @stream.verify
89
- assert router.verify
49
+ describe 'when addressed to a non-pubsub component' do
50
+ let(:router) { MiniTest::Mock.new }
51
+ let(:xml) { publish('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
90
63
  end
91
64
 
92
- def test_multiple_publish_elements_raises
93
- node = node(%q{
94
- <iq type='set' to='games.wonderland.lit' id='42'>
95
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
96
- <publish node='game_13'>
97
- <item id='item_42'>
98
- <entry xmlns='http://www.w3.org/2005/Atom'>
99
- <title>Test</title>
100
- <summary>This is a summary.</summary>
101
- </entry>
102
- </item>
103
- </publish>
104
- <publish node='game_13'>
105
- <item id='item_42'>
106
- <entry xmlns='http://www.w3.org/2005/Atom'>
107
- <title>Test</title>
108
- <summary>This is a summary.</summary>
109
- </entry>
110
- </item>
111
- </publish>
112
- </pubsub>
113
- </iq>
114
- }.strip.gsub(/\n|\s{2,}/, ''))
115
-
116
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
117
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
118
- assert @stream.verify
65
+ describe 'when publishing to multiple nodes' do
66
+ let(:xml) do
67
+ node(%q{
68
+ <iq type='set' to='games.wonderland.lit' id='42'>
69
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
70
+ <publish node='game_13'>
71
+ <item id='item_42'>
72
+ <entry xmlns='http://www.w3.org/2005/Atom'>
73
+ <title>Test</title>
74
+ <summary>This is a summary.</summary>
75
+ </entry>
76
+ </item>
77
+ </publish>
78
+ <publish node='game_13'>
79
+ <item id='item_42'>
80
+ <entry xmlns='http://www.w3.org/2005/Atom'>
81
+ <title>Test</title>
82
+ <summary>This is a summary.</summary>
83
+ </entry>
84
+ </item>
85
+ </publish>
86
+ </pubsub>
87
+ </iq>
88
+ })
89
+ end
90
+
91
+ it 'raises a bad-request stanza error' do
92
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
93
+ stream.verify
94
+ end
119
95
  end
120
96
 
121
- def test_multiple_item_elements_raises
122
- node = node(%q{
123
- <iq type='set' to='games.wonderland.lit' id='42'>
124
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
125
- <publish node='game_13'>
126
- <item id='item_42'>
127
- <entry xmlns='http://www.w3.org/2005/Atom'>
128
- <title>Test</title>
129
- <summary>This is a summary.</summary>
130
- </entry>
131
- </item>
132
- <item id="item_43">bad</item>
133
- </publish>
134
- </pubsub>
135
- </iq>
136
- }.strip.gsub(/\n|\s{2,}/, ''))
137
-
138
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
139
- def stanza.mock_pubsub; @mock_pubsub; end
140
- def stanza.pubsub
141
- unless @mock_pubsub
142
- @mock_pubsub = MiniTest::Mock.new
143
- @mock_pubsub.expect(:node?, true, ['game_13'])
97
+ describe 'when publishing multiple items' do
98
+ let(:pubsub) { MiniTest::Mock.new }
99
+ let(:xml) do
100
+ node(%q{
101
+ <iq type='set' to='games.wonderland.lit' id='42'>
102
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
103
+ <publish node='game_13'>
104
+ <item id='item_42'>
105
+ <entry xmlns='http://www.w3.org/2005/Atom'>
106
+ <title>Test</title>
107
+ <summary>This is a summary.</summary>
108
+ </entry>
109
+ </item>
110
+ <item id="item_43">bad</item>
111
+ </publish>
112
+ </pubsub>
113
+ </iq>
114
+ })
115
+ end
116
+
117
+ it 'raises a bad-request stanza error' do
118
+ pubsub.expect :node?, true, ['game_13']
119
+ subject.stub :pubsub, pubsub do
120
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
144
121
  end
145
- @mock_pubsub
122
+ stream.verify
123
+ pubsub.verify
146
124
  end
147
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
148
- assert @stream.verify
149
- assert stanza.mock_pubsub.verify
150
125
  end
151
126
 
152
- def test_multiple_payload_elements_raises
153
- node = node(%q{
154
- <iq type='set' to='games.wonderland.lit' id='42'>
155
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
156
- <publish node='game_13'>
157
- <item id='item_42'>
158
- <entry xmlns='http://www.w3.org/2005/Atom'>
159
- <title>Test</title>
160
- <summary>This is a summary.</summary>
161
- </entry>
162
- <entry>bad</entry>
163
- </item>
164
- </publish>
165
- </pubsub>
166
- </iq>
167
- }.strip.gsub(/\n|\s{2,}/, ''))
168
-
169
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
170
- def stanza.mock_pubsub; @mock_pubsub; end
171
- def stanza.pubsub
172
- unless @mock_pubsub
173
- @mock_pubsub = MiniTest::Mock.new
174
- @mock_pubsub.expect(:node?, true, ['game_13'])
127
+ describe 'when publishing one item with multiple payloads' do
128
+ let(:pubsub) { MiniTest::Mock.new }
129
+ let(:xml) do
130
+ node(%q{
131
+ <iq type='set' to='games.wonderland.lit' id='42'>
132
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
133
+ <publish node='game_13'>
134
+ <item id='item_42'>
135
+ <entry xmlns='http://www.w3.org/2005/Atom'>
136
+ <title>Test</title>
137
+ <summary>This is a summary.</summary>
138
+ </entry>
139
+ <entry>bad</entry>
140
+ </item>
141
+ </publish>
142
+ </pubsub>
143
+ </iq>
144
+ })
145
+ end
146
+
147
+ it 'raises a bad-request stanza error' do
148
+ pubsub.expect :node?, true, ['game_13']
149
+ subject.stub :pubsub, pubsub do
150
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
175
151
  end
176
- @mock_pubsub
152
+ stream.verify
153
+ pubsub.verify
177
154
  end
178
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
179
- assert @stream.verify
180
- assert stanza.mock_pubsub.verify
181
155
  end
182
156
 
183
- def test_no_payload_elements_raises
184
- node = node(%q{
185
- <iq type='set' to='games.wonderland.lit' id='42'>
186
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
187
- <publish node='game_13'>
188
- <item id='item_42'>
189
- </item>
190
- </publish>
191
- </pubsub>
192
- </iq>
193
- }.strip.gsub(/\n|\s{2,}/, ''))
194
-
195
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
196
- def stanza.mock_pubsub; @mock_pubsub; end
197
- def stanza.pubsub
198
- unless @mock_pubsub
199
- @mock_pubsub = MiniTest::Mock.new
200
- @mock_pubsub.expect(:node?, true, ['game_13'])
201
- end
202
- @mock_pubsub
157
+ describe 'when publishing with no payload' do
158
+ let(:pubsub) { MiniTest::Mock.new }
159
+ let(:xml) do
160
+ node(%q{
161
+ <iq type='set' to='games.wonderland.lit' id='42'>
162
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
163
+ <publish node='game_13'>
164
+ <item id='item_42'>
165
+ </item>
166
+ </publish>
167
+ </pubsub>
168
+ </iq>
169
+ })
203
170
  end
204
171
 
205
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
206
- assert @stream.verify
207
- assert stanza.mock_pubsub.verify
172
+ it 'raises a bad-request stanza error' do
173
+ pubsub.expect :node?, true, ['game_13']
174
+ subject.stub :pubsub, pubsub do
175
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
176
+ end
177
+ stream.verify
178
+ pubsub.verify
179
+ end
208
180
  end
209
181
 
210
- def test_publish_to_missing_node_raises
211
- node = node(%q{
212
- <iq type='set' to='games.wonderland.lit' id='42'>
213
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
214
- <publish node='game_13'>
215
- <item id='item_42'>
216
- <entry xmlns='http://www.w3.org/2005/Atom'>
217
- <title>Test</title>
218
- <summary>This is a summary.</summary>
219
- </entry>
220
- </item>
221
- </publish>
222
- </pubsub>
223
- </iq>
224
- }.strip.gsub(/\n|\s{2,}/, ''))
225
-
226
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
227
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
228
- assert @stream.verify
182
+ describe 'when publishing to a missing node' do
183
+ let(:xml) { publish('games.wonderland.lit') }
184
+
185
+ it 'raises an item-not-found stanza error' do
186
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
187
+ stream.verify
188
+ end
229
189
  end
230
190
 
231
- def test_generate_item_id
232
- node = node(%q{
233
- <iq type='set' to='games.wonderland.lit' id='42'>
234
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
235
- <publish node='game_13'>
236
- <item>
237
- <entry xmlns='http://www.w3.org/2005/Atom'>
238
- <title>Test</title>
239
- <summary>This is a summary.</summary>
240
- </entry>
241
- </item>
242
- </publish>
243
- </pubsub>
244
- </iq>
245
- }.strip.gsub(/\n|\s{2,}/, ''))
246
-
247
- def @stream.nodes; @nodes; end
248
- def @stream.write(node)
249
- @nodes ||= []
250
- @nodes << node
191
+ describe 'when publishing an item without an id' do
192
+ let(:pubsub) { MiniTest::Mock.new }
193
+ let(:xml) { publish('games.wonderland.lit', '') }
194
+ let(:broadcast) { message_broadcast('') }
195
+ let(:response) do
196
+ node(%q{
197
+ <iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
198
+ <pubsub xmlns="http://jabber.org/protocol/pubsub">
199
+ <publish node="game_13">
200
+ <item/>
201
+ </publish>
202
+ </pubsub>
203
+ </iq>})
251
204
  end
252
205
 
253
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
254
- def stanza.mock_pubsub; @mock_pubsub; end
255
- def stanza.pubsub
256
- unless @mock_pubsub
257
- @mock_pubsub = MiniTest::Mock.new
258
- @mock_pubsub.expect(:node?, true, ['game_13'])
259
- def @mock_pubsub.published; @published; end
260
- def @mock_pubsub.publish(node, message)
261
- @published ||= []
262
- @published << [node, message]
263
- end
206
+ before do
207
+ pubsub.expect :node?, true, ['game_13']
208
+ def pubsub.published; @published; end
209
+ def pubsub.publish(node, message)
210
+ @published ||= []
211
+ @published << [node, message]
264
212
  end
265
- @mock_pubsub
266
213
  end
267
- stanza.process
268
-
269
- assert @stream.verify
270
- assert stanza.mock_pubsub.verify
271
- assert_equal 1, @stream.nodes.size
272
-
273
- # test result stanza contains generated item id
274
- expected = node(%q{
275
- <iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
276
- <pubsub xmlns="http://jabber.org/protocol/pubsub">
277
- <publish node="game_13">
278
- <item/>
279
- </publish>
280
- </pubsub>
281
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
214
+
215
+ it 'generates an item id in the response' do
216
+ subject.stub :pubsub, pubsub do
217
+ subject.process
218
+ end
219
+ stream.verify
220
+ pubsub.verify
221
+ stream.nodes.size.must_equal 1
222
+
282
223
  # id is random
283
- item = @stream.nodes[0].xpath('ns:pubsub/ns:publish/ns:item', 'ns' => 'http://jabber.org/protocol/pubsub').first
284
- refute_nil item['id']
224
+ item = stream.nodes.first.xpath('ns:pubsub/ns:publish/ns:item',
225
+ 'ns' => 'http://jabber.org/protocol/pubsub').first
226
+ item['id'].wont_be_nil
285
227
  item.remove_attribute('id')
286
- assert_equal expected, @stream.nodes[0]
287
-
288
- # test published message has a generated item id
289
- expected = node(%q{
290
- <message>
291
- <event xmlns="http://jabber.org/protocol/pubsub#event">
292
- <items node="game_13">
293
- <item publisher="alice@wonderland.lit/tea">
294
- <entry xmlns="http://www.w3.org/2005/Atom">
295
- <title>Test</title>
296
- <summary>This is a summary.</summary>
297
- </entry>
298
- </item>
299
- </items>
300
- </event>
301
- </message>
302
- }.strip.gsub(/\n|\s{2,}/, ''))
303
- published_node, published_message = *stanza.mock_pubsub.published[0]
304
- assert_equal 'game_13', published_node
228
+ stream.nodes.first.must_equal response
229
+ end
230
+
231
+ it 'broadcasts the message with the generated item id' do
232
+ subject.stub :pubsub, pubsub do
233
+ subject.process
234
+ end
235
+ stream.verify
236
+ pubsub.verify
237
+ stream.nodes.size.must_equal 1
238
+
239
+ published_node, published_message = *pubsub.published[0]
240
+ published_node.must_equal 'game_13'
305
241
  # id is random
306
- item = published_message.xpath('ns:event/ns:items/ns:item', 'ns' => 'http://jabber.org/protocol/pubsub#event').first
307
- refute_nil item['id']
242
+ item = published_message.xpath('ns:event/ns:items/ns:item',
243
+ 'ns' => 'http://jabber.org/protocol/pubsub#event').first
244
+ item['id'].wont_be_nil
308
245
  item.remove_attribute('id')
309
- assert_equal expected, published_message
246
+ published_message.must_equal broadcast
247
+ end
310
248
  end
311
249
 
312
- def test_good_stanza_processes
313
- node = node(%q{
314
- <iq type='set' to='games.wonderland.lit' id='42'>
315
- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
316
- <publish node='game_13'>
317
- <item id='item_42'>
318
- <entry xmlns='http://www.w3.org/2005/Atom'>
319
- <title>Test</title>
320
- <summary>This is a summary.</summary>
321
- </entry>
322
- </item>
323
- </publish>
324
- </pubsub>
325
- </iq>
326
- }.strip.gsub(/\n|\s{2,}/, ''))
327
-
328
- def @stream.nodes; @nodes; end
329
- def @stream.write(node)
330
- @nodes ||= []
331
- @nodes << node
332
- end
250
+ describe 'when publishing a valid stanza' do
251
+ let(:pubsub) { MiniTest::Mock.new }
252
+ let(:xml) { publish('games.wonderland.lit') }
253
+ let(:response) { result(user.jid, 'games.wonderland.lit') }
254
+ let(:broadcast) { message_broadcast('item_42') }
255
+
256
+ it 'broadcasts and returns result to sender' do
257
+ pubsub.expect :node?, true, ['game_13']
258
+ pubsub.expect :publish, nil, ['game_13', broadcast]
333
259
 
334
- stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
335
- def stanza.mock_pubsub; @mock_pubsub; end
336
- def stanza.pubsub
337
- unless @mock_pubsub
338
- xml = %q{
339
- <message>
340
- <event xmlns="http://jabber.org/protocol/pubsub#event">
341
- <items node="game_13">
342
- <item id="item_42" publisher="alice@wonderland.lit/tea">
343
- <entry xmlns="http://www.w3.org/2005/Atom">
344
- <title>Test</title>
345
- <summary>This is a summary.</summary>
346
- </entry>
347
- </item>
348
- </items>
349
- </event>
350
- </message>
351
- }.strip.gsub(/\n|\s{2,}/, '')
352
- @mock_pubsub = MiniTest::Mock.new
353
- @mock_pubsub.expect(:node?, true, ['game_13'])
354
- @mock_pubsub.expect(:publish, nil, ['game_13', Nokogiri::XML(xml).root])
260
+ subject.stub :pubsub, pubsub do
261
+ subject.process
355
262
  end
356
- @mock_pubsub
263
+
264
+ stream.nodes.size.must_equal 1
265
+ stream.nodes.first.must_equal response
266
+ stream.verify
267
+ pubsub.verify
357
268
  end
358
- stanza.process
269
+ end
359
270
 
360
- assert @stream.verify
361
- assert stanza.mock_pubsub.verify
362
- assert_equal 1, @stream.nodes.size
271
+ private
363
272
 
364
- expected = node(%q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
365
- assert_equal expected, @stream.nodes[0]
273
+ def message_broadcast(item_id)
274
+ item_id = (item_id.nil? || item_id.empty?) ? ' ' : " id='#{item_id}' "
275
+ node(%Q{
276
+ <message>
277
+ <event xmlns="http://jabber.org/protocol/pubsub#event">
278
+ <items node="game_13">
279
+ <item#{item_id}publisher="alice@wonderland.lit/tea">
280
+ <entry xmlns="http://www.w3.org/2005/Atom">
281
+ <title>Test</title>
282
+ <summary>This is a summary.</summary>
283
+ </entry>
284
+ </item>
285
+ </items>
286
+ </event>
287
+ </message>})
366
288
  end
367
289
 
368
- private
290
+ def publish(to, item_id='item_42')
291
+ item_id = "id='#{item_id}'" unless item_id.nil? || item_id.empty?
292
+ body = %Q{
293
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
294
+ <publish node='game_13'>
295
+ <item #{item_id}>
296
+ <entry xmlns='http://www.w3.org/2005/Atom'>
297
+ <title>Test</title>
298
+ <summary>This is a summary.</summary>
299
+ </entry>
300
+ </item>
301
+ </publish>
302
+ </pubsub>}
303
+ iq(type: 'set', to: to, id: 42, body: body)
304
+ end
369
305
 
370
- def node(xml)
371
- Nokogiri::XML(xml).root
306
+ def result(to, from)
307
+ iq(from: from, id: 42, to: to, type: 'result')
372
308
  end
373
309
  end