sprsquish-blather 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +41 -12
  3. data/examples/echo.rb +1 -1
  4. data/examples/execute.rb +0 -5
  5. data/examples/pubsub/cli.rb +64 -0
  6. data/examples/pubsub/ping_pong.rb +18 -0
  7. data/examples/rosterprint.rb +14 -0
  8. data/examples/xmpp4r/echo.rb +35 -0
  9. data/lib/blather/client/client.rb +19 -13
  10. data/lib/blather/client/dsl/pubsub.rb +133 -0
  11. data/lib/blather/client/dsl.rb +16 -0
  12. data/lib/blather/client.rb +1 -1
  13. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
  14. data/lib/blather/core_ext/active_support.rb +1 -117
  15. data/lib/blather/core_ext/nokogiri.rb +35 -0
  16. data/lib/blather/errors/sasl_error.rb +3 -1
  17. data/lib/blather/errors/stanza_error.rb +10 -17
  18. data/lib/blather/errors/stream_error.rb +11 -14
  19. data/lib/blather/errors.rb +3 -20
  20. data/lib/blather/jid.rb +1 -0
  21. data/lib/blather/roster.rb +9 -0
  22. data/lib/blather/roster_item.rb +6 -1
  23. data/lib/blather/stanza/disco/disco_info.rb +45 -33
  24. data/lib/blather/stanza/disco/disco_items.rb +32 -21
  25. data/lib/blather/stanza/disco.rb +7 -1
  26. data/lib/blather/stanza/iq/query.rb +16 -8
  27. data/lib/blather/stanza/iq/roster.rb +33 -22
  28. data/lib/blather/stanza/iq.rb +13 -8
  29. data/lib/blather/stanza/message.rb +20 -31
  30. data/lib/blather/stanza/presence/status.rb +13 -21
  31. data/lib/blather/stanza/presence/subscription.rb +11 -16
  32. data/lib/blather/stanza/presence.rb +3 -5
  33. data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
  34. data/lib/blather/stanza/pubsub/create.rb +43 -0
  35. data/lib/blather/stanza/pubsub/errors.rb +9 -0
  36. data/lib/blather/stanza/pubsub/event.rb +77 -0
  37. data/lib/blather/stanza/pubsub/items.rb +63 -0
  38. data/lib/blather/stanza/pubsub/publish.rb +58 -0
  39. data/lib/blather/stanza/pubsub/retract.rb +53 -0
  40. data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
  41. data/lib/blather/stanza/pubsub/subscription.rb +66 -0
  42. data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
  43. data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
  44. data/lib/blather/stanza/pubsub.rb +63 -0
  45. data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
  46. data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
  47. data/lib/blather/stanza/pubsub_owner.rb +41 -0
  48. data/lib/blather/stanza.rb +35 -18
  49. data/lib/blather/stream/client.rb +1 -2
  50. data/lib/blather/stream/component.rb +9 -5
  51. data/lib/blather/stream/features/resource.rb +63 -0
  52. data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
  53. data/lib/blather/stream/features/session.rb +44 -0
  54. data/lib/blather/stream/features/tls.rb +28 -0
  55. data/lib/blather/stream/features.rb +53 -0
  56. data/lib/blather/stream/parser.rb +70 -46
  57. data/lib/blather/stream.rb +76 -168
  58. data/lib/blather/xmpp_node.rb +113 -52
  59. data/lib/blather.rb +35 -12
  60. data/spec/blather/client/client_spec.rb +44 -58
  61. data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
  62. data/spec/blather/client/dsl_spec.rb +19 -6
  63. data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
  64. data/spec/blather/errors/sasl_error_spec.rb +8 -8
  65. data/spec/blather/errors/stanza_error_spec.rb +25 -33
  66. data/spec/blather/errors/stream_error_spec.rb +21 -16
  67. data/spec/blather/errors_spec.rb +4 -11
  68. data/spec/blather/jid_spec.rb +31 -30
  69. data/spec/blather/roster_item_spec.rb +34 -23
  70. data/spec/blather/roster_spec.rb +27 -12
  71. data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
  72. data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
  73. data/spec/blather/stanza/iq/query_spec.rb +34 -11
  74. data/spec/blather/stanza/iq/roster_spec.rb +47 -30
  75. data/spec/blather/stanza/iq_spec.rb +19 -14
  76. data/spec/blather/stanza/message_spec.rb +30 -17
  77. data/spec/blather/stanza/presence/status_spec.rb +43 -20
  78. data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
  79. data/spec/blather/stanza/presence_spec.rb +34 -21
  80. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  81. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  82. data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
  83. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  84. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  85. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  86. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  87. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  88. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  89. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
  90. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  91. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  92. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  93. data/spec/blather/stanza/pubsub_spec.rb +62 -0
  94. data/spec/blather/stanza_spec.rb +53 -38
  95. data/spec/blather/stream/client_spec.rb +231 -88
  96. data/spec/blather/stream/component_spec.rb +14 -5
  97. data/spec/blather/stream/parser_spec.rb +145 -0
  98. data/spec/blather/xmpp_node_spec.rb +192 -96
  99. data/spec/fixtures/pubsub.rb +311 -0
  100. data/spec/spec_helper.rb +5 -4
  101. metadata +53 -17
  102. data/Rakefile +0 -139
  103. data/ext/extconf.rb +0 -65
  104. data/ext/push_parser.c +0 -209
  105. data/lib/blather/core_ext/libxml.rb +0 -28
  106. data/lib/blather/stream/resource.rb +0 -48
  107. data/lib/blather/stream/session.rb +0 -36
  108. data/lib/blather/stream/stream_handler.rb +0 -39
  109. data/lib/blather/stream/tls.rb +0 -33
  110. data/spec/blather/core_ext/libxml_spec.rb +0 -58
@@ -0,0 +1,465 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. fixtures pubsub])
3
+ require 'blather/client/dsl'
4
+
5
+ describe Blather::DSL::PubSub do
6
+ before do
7
+ @host = 'host.name'
8
+ @pubsub = Blather::DSL::PubSub.new @host
9
+ @client = mock()
10
+ @client.stubs(:jid).returns Blather::JID.new('n@d/r')
11
+ Blather::DSL.stubs(:client).returns @client
12
+ end
13
+
14
+ it 'raises an error when trying to send a stanza without a host' do
15
+ @pubsub.host = nil
16
+ proc { @pubsub.affiliations }.must_raise RuntimeError
17
+ end
18
+
19
+ it 'requests affiliations' do
20
+ @client.expects(:write_with_handler).with do |n|
21
+ n.must_be_instance_of Blather::Stanza::PubSub::Affiliations
22
+ n.find('//ns:pubsub/ns:affiliations', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
23
+ n.to.must_equal Blather::JID.new(@host)
24
+ n.type.must_equal :get
25
+ end
26
+ @pubsub.affiliations
27
+ end
28
+
29
+ it 'requests affiliations from a specified host' do
30
+ host = 'another.host'
31
+ @client.expects(:write_with_handler).with do |n|
32
+ n.must_be_instance_of Blather::Stanza::PubSub::Affiliations
33
+ n.find('//ns:pubsub/ns:affiliations', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
34
+ n.to.must_equal Blather::JID.new(host)
35
+ n.type.must_equal :get
36
+ end
37
+ @pubsub.affiliations host
38
+ end
39
+
40
+ it 'requests subscriptions' do
41
+ @client.expects(:write_with_handler).with do |n|
42
+ n.must_be_instance_of Blather::Stanza::PubSub::Subscriptions
43
+ n.find('//ns:pubsub/ns:subscriptions', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
44
+ n.to.must_equal Blather::JID.new(@host)
45
+ n.type.must_equal :get
46
+ end
47
+ @pubsub.subscriptions
48
+ end
49
+
50
+ it 'requests subscriptions from a specified host' do
51
+ host = 'another.host'
52
+ @client.expects(:write_with_handler).with do |n|
53
+ n.must_be_instance_of Blather::Stanza::PubSub::Subscriptions
54
+ n.find('//ns:pubsub/ns:subscriptions', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
55
+ n.to.must_equal Blather::JID.new(host)
56
+ n.type.must_equal :get
57
+ end
58
+ @pubsub.subscriptions host
59
+ end
60
+
61
+ it 'requests nodes defaulting to "/"' do
62
+ @client.expects(:write_with_handler).with do |n|
63
+ n.must_be_instance_of Blather::Stanza::DiscoItems
64
+ n.find("/iq/ns:query[@node='/']", :ns => Blather::Stanza::DiscoItems.registered_ns).wont_be_empty
65
+ n.to.must_equal Blather::JID.new(@host)
66
+ n.type.must_equal :get
67
+ end
68
+ @pubsub.nodes nil
69
+ end
70
+
71
+ it 'requests nodes from a specified host' do
72
+ host = 'another.host'
73
+ @client.expects(:write_with_handler).with do |n|
74
+ n.must_be_instance_of Blather::Stanza::DiscoItems
75
+ n.find("/iq/ns:query[@node='/']", :ns => Blather::Stanza::DiscoItems.registered_ns).wont_be_empty
76
+ n.to.must_equal Blather::JID.new(host)
77
+ n.type.must_equal :get
78
+ end
79
+ @pubsub.nodes nil, host
80
+ end
81
+
82
+ it 'requests nodes under a specified path' do
83
+ @client.expects(:write_with_handler).with do |n|
84
+ n.must_be_instance_of Blather::Stanza::DiscoItems
85
+ n.find("/iq/ns:query[@node='/path/to/nodes']", :ns => Blather::Stanza::DiscoItems.registered_ns).wont_be_empty
86
+ n.to.must_equal Blather::JID.new(@host)
87
+ n.type.must_equal :get
88
+ end
89
+ @pubsub.nodes '/path/to/nodes'
90
+ end
91
+
92
+ it 'requests information on a node' do
93
+ @client.expects(:write_with_handler).with do |n|
94
+ n.must_be_instance_of Blather::Stanza::DiscoInfo
95
+ n.find("/iq/ns:query[@node='/path/to/node']", :ns => Blather::Stanza::DiscoInfo.registered_ns).wont_be_empty
96
+ n.to.must_equal Blather::JID.new(@host)
97
+ n.type.must_equal :get
98
+ end
99
+ @pubsub.node '/path/to/node'
100
+ end
101
+
102
+ it 'requests all items from a node' do
103
+ @client.expects(:write_with_handler).with do |n|
104
+ n.must_be_instance_of Blather::Stanza::PubSub::Items
105
+ n.find("/iq/ns:pubsub/ns:items[@node='/path/to/node']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
106
+ n.to.must_equal Blather::JID.new(@host)
107
+ n.type.must_equal :get
108
+ end
109
+ @pubsub.items '/path/to/node'
110
+ end
111
+
112
+ it 'requests specific items from a node' do
113
+ @client.expects(:write_with_handler).with do |n|
114
+ n.must_be_instance_of Blather::Stanza::PubSub::Items
115
+ n.find("/iq/ns:pubsub/ns:items[@node='/path/to/node'][ns:item[@id='item1']][ns:item[@id='item2']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
116
+ n.to.must_equal Blather::JID.new(@host)
117
+ n.type.must_equal :get
118
+ end
119
+ @pubsub.items '/path/to/node', %w[item1 item2]
120
+ end
121
+
122
+ it 'requests some items from a node' do
123
+ @client.expects(:write_with_handler).with do |n|
124
+ n.must_be_instance_of Blather::Stanza::PubSub::Items
125
+ n.find("/iq/ns:pubsub/ns:items[@node='/path/to/node' and @max_items='2']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
126
+ n.to.must_equal Blather::JID.new(@host)
127
+ n.type.must_equal :get
128
+ end
129
+ @pubsub.items '/path/to/node', nil, 2
130
+ end
131
+
132
+ it 'can publish items to a node with a hash' do
133
+ @client.expects(:write_with_handler).with do |n|
134
+ n.must_be_instance_of Blather::Stanza::PubSub::Publish
135
+ n.find("/iq[@type='set']/ns:pubsub/ns:publish[@node='/path/to/node' and ns:item[@id='id1' and .='payload1'] and ns:item[@id='id2' and .='payload2']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
136
+ n.to.must_equal Blather::JID.new(@host)
137
+ n.type.must_equal :set
138
+ end
139
+ @pubsub.publish '/path/to/node', {'id1' => 'payload1', 'id2' => 'payload2'}
140
+ end
141
+
142
+ it 'can publish items to a node with an array' do
143
+ @client.expects(:write_with_handler).with do |n|
144
+ n.must_be_instance_of Blather::Stanza::PubSub::Publish
145
+ n.find("/iq[@type='set']/ns:pubsub/ns:publish[@node='/path/to/node' and ns:item[.='payload1'] and ns:item[.='payload2']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
146
+ n.to.must_equal Blather::JID.new(@host)
147
+ n.type.must_equal :set
148
+ end
149
+ @pubsub.publish '/path/to/node', %w[payload1 payload2]
150
+ end
151
+
152
+ it 'can publish items to a node with a string' do
153
+ @client.expects(:write_with_handler).with do |n|
154
+ n.must_be_instance_of Blather::Stanza::PubSub::Publish
155
+ n.find("/iq[@type='set']/ns:pubsub/ns:publish[@node='/path/to/node' and ns:item[.='payload']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
156
+ n.to.must_equal Blather::JID.new(@host)
157
+ n.type.must_equal :set
158
+ end
159
+ @pubsub.publish '/path/to/node', 'payload'
160
+ end
161
+
162
+ it 'can retract an item with an array' do
163
+ @client.expects(:write_with_handler).with do |n|
164
+ n.must_be_instance_of Blather::Stanza::PubSub::Retract
165
+ n.find("/iq[@type='set']/ns:pubsub/ns:retract[@node='/path/to/node' and ns:item[@id='id1'] and ns:item[@id='id2']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
166
+ n.to.must_equal Blather::JID.new(@host)
167
+ n.type.must_equal :set
168
+ end
169
+ @pubsub.retract '/path/to/node', %w[id1 id2]
170
+ end
171
+
172
+ it 'can retract an item with a string' do
173
+ @client.expects(:write_with_handler).with do |n|
174
+ n.must_be_instance_of Blather::Stanza::PubSub::Retract
175
+ n.find("/iq[@type='set']/ns:pubsub/ns:retract[@node='/path/to/node' and ns:item[@id='id1']]", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
176
+ n.to.must_equal Blather::JID.new(@host)
177
+ n.type.must_equal :set
178
+ end
179
+ @pubsub.retract '/path/to/node', 'id1'
180
+ end
181
+
182
+ it 'can subscribe to a node with the default jid' do
183
+ @client.expects(:write_with_handler).with do |n|
184
+ n.must_be_instance_of Blather::Stanza::PubSub::Subscribe
185
+ n.find("/iq[@type='set']/ns:pubsub/ns:subscribe[@node='/path/to/node' and @jid='#{@client.jid.stripped}']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
186
+ n.to.must_equal Blather::JID.new(@host)
187
+ n.type.must_equal :set
188
+ end
189
+ @pubsub.subscribe '/path/to/node'
190
+ end
191
+
192
+ it 'can subscribe to a node with a specified jid as a string' do
193
+ @client.expects(:write_with_handler).with do |n|
194
+ n.must_be_instance_of Blather::Stanza::PubSub::Subscribe
195
+ n.find("/iq[@type='set']/ns:pubsub/ns:subscribe[@node='/path/to/node' and @jid='jid@d/r']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
196
+ n.to.must_equal Blather::JID.new(@host)
197
+ n.type.must_equal :set
198
+ end
199
+ @pubsub.subscribe '/path/to/node', 'jid@d/r'
200
+ end
201
+
202
+ it 'can subscribe to a node with a specified jid as a Blather::JID' do
203
+ @client.expects(:write_with_handler).with do |n|
204
+ n.must_be_instance_of Blather::Stanza::PubSub::Subscribe
205
+ n.find("/iq[@type='set']/ns:pubsub/ns:subscribe[@node='/path/to/node' and @jid='jid@d/r']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
206
+ n.to.must_equal Blather::JID.new(@host)
207
+ n.type.must_equal :set
208
+ end
209
+ @pubsub.subscribe '/path/to/node', Blather::JID.new('jid@d/r')
210
+ end
211
+
212
+ it 'can unsubscribe to a node with the default jid' do
213
+ @client.expects(:write_with_handler).with do |n|
214
+ n.must_be_instance_of Blather::Stanza::PubSub::Unsubscribe
215
+ n.find("/iq[@type='set']/ns:pubsub/ns:unsubscribe[@node='/path/to/node' and @jid='#{@client.jid.stripped}']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
216
+ n.to.must_equal Blather::JID.new(@host)
217
+ n.type.must_equal :set
218
+ end
219
+ @pubsub.unsubscribe '/path/to/node'
220
+ end
221
+
222
+ it 'can unsubscribe to a node with a specified jid as a string' do
223
+ @client.expects(:write_with_handler).with do |n|
224
+ n.must_be_instance_of Blather::Stanza::PubSub::Unsubscribe
225
+ n.find("/iq[@type='set']/ns:pubsub/ns:unsubscribe[@node='/path/to/node' and @jid='jid@d/r']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
226
+ n.to.must_equal Blather::JID.new(@host)
227
+ n.type.must_equal :set
228
+ end
229
+ @pubsub.unsubscribe '/path/to/node', 'jid@d/r'
230
+ end
231
+
232
+ it 'can unsubscribe to a node with a specified jid as a Blather::JID' do
233
+ @client.expects(:write_with_handler).with do |n|
234
+ n.must_be_instance_of Blather::Stanza::PubSub::Unsubscribe
235
+ n.find("/iq[@type='set']/ns:pubsub/ns:unsubscribe[@node='/path/to/node' and @jid='jid@d/r']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
236
+ n.to.must_equal Blather::JID.new(@host)
237
+ n.type.must_equal :set
238
+ end
239
+ @pubsub.unsubscribe '/path/to/node', Blather::JID.new('jid@d/r')
240
+ end
241
+
242
+ it 'can purge a node' do
243
+ @client.expects(:write_with_handler).with do |n|
244
+ n.must_be_instance_of Blather::Stanza::PubSubOwner::Purge
245
+ n.find("/iq[@type='set']/ns:pubsub/ns:purge[@node='/path/to/node']", :ns => Blather::Stanza::PubSubOwner.registered_ns).wont_be_empty
246
+ n.to.must_equal Blather::JID.new(@host)
247
+ n.type.must_equal :set
248
+ end
249
+ @pubsub.purge '/path/to/node'
250
+ end
251
+
252
+ it 'can create a node' do
253
+ @client.expects(:write_with_handler).with do |n|
254
+ n.must_be_instance_of Blather::Stanza::PubSub::Create
255
+ n.find("/iq[@type='set']/ns:pubsub/ns:create[@node='/path/to/node']", :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
256
+ n.to.must_equal Blather::JID.new(@host)
257
+ n.type.must_equal :set
258
+ end
259
+ @pubsub.create '/path/to/node'
260
+ end
261
+
262
+ it 'can delete a node' do
263
+ @client.expects(:write_with_handler).with do |n|
264
+ n.must_be_instance_of Blather::Stanza::PubSubOwner::Delete
265
+ n.find("/iq[@type='set']/ns:pubsub/ns:delete[@node='/path/to/node']", :ns => Blather::Stanza::PubSubOwner.registered_ns).wont_be_empty
266
+ n.to.must_equal Blather::JID.new(@host)
267
+ n.type.must_equal :set
268
+ end
269
+ @pubsub.delete '/path/to/node'
270
+ end
271
+ end
272
+
273
+ describe 'Blather::DSL::PubSub callbacks' do
274
+ before do
275
+ @host = 'host.name'
276
+ @pubsub = Blather::DSL::PubSub.new @host
277
+ @client = Blather::Client.new
278
+ @client.jid = Blather::JID.new('n@d/r')
279
+ Blather::DSL.stubs(:client).returns @client
280
+ end
281
+
282
+ it 'returns a list of affiliations when requesting affiliations' do
283
+ affiliations = Blather::XMPPNode.import(parse_stanza(affiliations_xml).root)
284
+ response = mock()
285
+ response.expects(:call).with { |n| n.must_equal affiliations.list }
286
+ @client.stubs(:write).with do |n|
287
+ affiliations.id = n.id
288
+ @client.receive_data affiliations
289
+ true
290
+ end
291
+ @pubsub.affiliations { |n| response.call n }
292
+ end
293
+
294
+ it 'returns a list of subscriptions when requesting subscriptions' do
295
+ subscriptions = Blather::XMPPNode.import(parse_stanza(subscriptions_xml).root)
296
+ response = mock()
297
+ response.expects(:call).with { |n| n.must_equal subscriptions.list }
298
+ @client.stubs(:write).with do |n|
299
+ subscriptions.id = n.id
300
+ @client.receive_data subscriptions
301
+ true
302
+ end
303
+ @pubsub.subscriptions { |n| response.call n }
304
+ end
305
+
306
+ it 'returns a list of node items when requesting nodes' do
307
+ nodes = Blather::XMPPNode.import(parse_stanza(<<-NODES).root)
308
+ <iq type='result'
309
+ from='pubsub.shakespeare.lit'
310
+ to='francisco@denmark.lit/barracks'
311
+ id='nodes1'>
312
+ <query xmlns='http://jabber.org/protocol/disco#items'>
313
+ <item jid='pubsub.shakespeare.lit'
314
+ node='blogs'
315
+ name='Weblog updates'/>
316
+ <item jid='pubsub.shakespeare.lit'
317
+ node='news'
318
+ name='News and announcements'/>
319
+ </query>
320
+ </iq>
321
+ NODES
322
+ response = mock()
323
+ response.expects(:call).with { |n| n.must_equal nodes.items }
324
+ @client.stubs(:write).with do |n|
325
+ nodes.id = n.id
326
+ @client.receive_data nodes
327
+ true
328
+ end
329
+ @pubsub.nodes { |n| response.call n }
330
+ end
331
+
332
+ it 'returns a DiscoInfo node when requesting a node' do
333
+ node = Blather::XMPPNode.import(parse_stanza(<<-NODES).root)
334
+ <iq type='result'
335
+ from='pubsub.shakespeare.lit'
336
+ to='francisco@denmark.lit/barracks'
337
+ id='meta1'>
338
+ <query xmlns='http://jabber.org/protocol/disco#info'
339
+ node='blogs'>
340
+ <identity category='pubsub' type='collection'/>
341
+ </query>
342
+ </iq>
343
+ NODES
344
+ response = mock()
345
+ response.expects(:call).with { |n| n.must_equal node }
346
+ @client.stubs(:write).with do |n|
347
+ node.id = n.id
348
+ @client.receive_data node
349
+ true
350
+ end
351
+ @pubsub.node('blogs') { |n| response.call n }
352
+ end
353
+
354
+ it 'returns a set of items when requesting items' do
355
+ items = Blather::XMPPNode.import(parse_stanza(items_all_nodes_xml).root)
356
+ response = mock()
357
+ response.expects(:call).with { |n| n.map{|i|i.to_s}.must_equal items.items.map{|i|i.to_s} }
358
+ @client.stubs(:write).with do |n|
359
+ items.id = n.id
360
+ @client.receive_data items
361
+ true
362
+ end
363
+ @pubsub.items('princely_musings') { |n| response.call n }
364
+ end
365
+
366
+ it 'returns aa subscription node when subscribing' do
367
+ subscription = Blather::XMPPNode.import(parse_stanza(subscription_xml).root)
368
+ response = mock()
369
+ response.expects(:call).with { |n| n.must_equal subscription }
370
+ @client.stubs(:write).with do |n|
371
+ subscription.id = n.id
372
+ @client.receive_data subscription
373
+ true
374
+ end
375
+ @pubsub.subscribe('princely_musings') { |n| response.call n }
376
+ end
377
+
378
+ it 'returns aa unsubscribe node when unsubscribing' do
379
+ unsubscribe = Blather::XMPPNode.import(parse_stanza(unsubscribe_xml).root)
380
+ response = mock()
381
+ response.expects(:call).with { |n| n.must_equal unsubscribe }
382
+ @client.stubs(:write).with do |n|
383
+ unsubscribe.id = n.id
384
+ @client.receive_data unsubscribe
385
+ true
386
+ end
387
+ @pubsub.unsubscribe('princely_musings') { |n| response.call n }
388
+ end
389
+
390
+ it 'returns a publish result when publishing to a node' do
391
+ result = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
392
+ <iq type='result'
393
+ from='pubsub.shakespeare.lit'
394
+ to='hamlet@denmark.lit/blogbot'
395
+ id='publish1'>
396
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
397
+ <publish node='princely_musings'>
398
+ <item id='ae890ac52d0df67ed7cfdf51b644e901'/>
399
+ </publish>
400
+ </pubsub>
401
+ </iq>
402
+ NODE
403
+ response = mock()
404
+ response.expects(:call).with { |n| n.must_equal result }
405
+ @client.stubs(:write).with do |n|
406
+ result.id = n.id
407
+ @client.receive_data result
408
+ true
409
+ end
410
+ @pubsub.publish('princely_musings', 'payload') { |n| response.call n }
411
+ end
412
+
413
+ it 'returns a create result when creating a node' do
414
+ result = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
415
+ <iq type='result'
416
+ from='pubsub.shakespeare.lit'
417
+ to='hamlet@denmark.lit/elsinore'
418
+ id='create2'>
419
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
420
+ <create node='25e3d37dabbab9541f7523321421edc5bfeb2dae'/>
421
+ </pubsub>
422
+ </iq>
423
+ NODE
424
+ response = mock()
425
+ response.expects(:call).with { |n| n.must_equal result }
426
+ @client.stubs(:write).with do |n|
427
+ result.id = n.id
428
+ @client.receive_data result
429
+ true
430
+ end
431
+ @pubsub.create('princely_musings') { |n| response.call n }
432
+ end
433
+
434
+ it 'returns a purge result when purging a node' do
435
+ result = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
436
+ <iq type='result'
437
+ from='pubsub.shakespeare.lit'
438
+ id='purge1'/>
439
+ NODE
440
+ response = mock()
441
+ response.expects(:call).with { |n| n.must_equal result }
442
+ @client.stubs(:write).with do |n|
443
+ result.id = n.id
444
+ @client.receive_data result
445
+ true
446
+ end
447
+ @pubsub.purge('princely_musings') { |n| response.call n }
448
+ end
449
+
450
+ it 'returns a delete result when deleting a node' do
451
+ result = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
452
+ <iq type='result'
453
+ from='pubsub.shakespeare.lit'
454
+ id='delete1'/>
455
+ NODE
456
+ response = mock()
457
+ response.expects(:call).with { |n| n.must_equal result }
458
+ @client.stubs(:write).with do |n|
459
+ result.id = n.id
460
+ @client.receive_data result
461
+ true
462
+ end
463
+ @pubsub.delete('princely_musings') { |n| response.call n }
464
+ end
465
+ end
@@ -1,11 +1,11 @@
1
1
  require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
2
2
  require 'blather/client/dsl'
3
3
 
4
- describe 'Blather::DSL' do
4
+ describe Blather::DSL do
5
5
  before do
6
6
  @client = mock()
7
- @dsl = class MockDSL; include Blather::DSL; end.new
8
- Client.stubs(:new).returns(@client)
7
+ @dsl = Class.new { include Blather::DSL }.new
8
+ Blather::Client.stubs(:new).returns(@client)
9
9
  end
10
10
 
11
11
  it 'wraps the setup' do
@@ -55,6 +55,12 @@ describe 'Blather::DSL' do
55
55
  @dsl.my_roster
56
56
  end
57
57
 
58
+ it 'provides a << style writer that provides chaining' do
59
+ stanza = Blather::Stanza::Iq.new
60
+ @client.expects(:write).with stanza
61
+ (@dsl << stanza).must_equal @dsl
62
+ end
63
+
58
64
  it 'provides a writer' do
59
65
  stanza = Blather::Stanza::Iq.new
60
66
  @client.expects(:write).with stanza
@@ -64,7 +70,7 @@ describe 'Blather::DSL' do
64
70
  it 'provides a "say" helper' do
65
71
  to, msg = 'me@me.com', 'hello!'
66
72
  Blather::Stanza::Message.stubs(:next_id).returns 0
67
- @client.expects(:write).with Blather::Stanza::Message.new(to, msg)
73
+ @client.expects(:write).with { |n| n.to_s.must_equal Blather::Stanza::Message.new(to, msg).to_s }
68
74
  @dsl.say to, msg
69
75
  end
70
76
 
@@ -80,7 +86,7 @@ describe 'Blather::DSL' do
80
86
  expected_stanza = Blather::Stanza::Disco::DiscoItems.new
81
87
  expected_stanza.to = who
82
88
  expected_stanza.node = where
83
- @client.expects(:write).with expected_stanza
89
+ @client.expects(:write).with { |n| n.to_s.must_equal expected_stanza.to_s }
84
90
  @dsl.discover what, who, where
85
91
  end
86
92
 
@@ -91,7 +97,7 @@ describe 'Blather::DSL' do
91
97
  expected_stanza = Blather::Stanza::Disco::DiscoInfo.new
92
98
  expected_stanza.to = who
93
99
  expected_stanza.node = where
94
- @client.expects(:write).with expected_stanza
100
+ @client.expects(:write).with { |n| n.to_s.must_equal expected_stanza.to_s }
95
101
  @dsl.discover what, who, where
96
102
  end
97
103
 
@@ -102,4 +108,11 @@ describe 'Blather::DSL' do
102
108
  @dsl.__send__(handler_method, *guards)
103
109
  end
104
110
  end
111
+
112
+ it 'has a pubsub helper set to the jid domain' do
113
+ jid = Blather::JID.new('jid@domain/resource')
114
+ @client.stubs(:jid).returns jid
115
+ @dsl.pubsub.must_be_instance_of Blather::DSL::PubSub
116
+ @dsl.pubsub.host.must_equal jid.domain
117
+ end
105
118
  end
@@ -0,0 +1,83 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
2
+
3
+ describe 'Nokogiri::XML::Node' do
4
+ before { @doc = Nokogiri::XML::Document.new }
5
+
6
+ it 'aliases #name to #element_name' do
7
+ node = Nokogiri::XML::Node.new 'foo', @doc
8
+ node.must_respond_to :element_name
9
+ node.element_name.must_equal node.name
10
+ end
11
+
12
+ it 'aliases #name= to #element_name=' do
13
+ node = Nokogiri::XML::Node.new 'foo', @doc
14
+ node.must_respond_to :element_name=
15
+ node.element_name.must_equal node.name
16
+ node.element_name = 'bar'
17
+ node.element_name.must_equal 'bar'
18
+ end
19
+
20
+ it 'allows symbols as hash keys for attributes' do
21
+ attrs = Nokogiri::XML::Node.new('foo', @doc)
22
+ attrs['foo'] = 'bar'
23
+
24
+ attrs['foo'].must_equal 'bar'
25
+ attrs[:foo].must_equal 'bar'
26
+ end
27
+
28
+ it 'ensures a string is passed to the attribute setter' do
29
+ attrs = Nokogiri::XML::Node.new('foo', @doc)
30
+ attrs[:foo] = 1
31
+ attrs[:foo].must_equal '1'
32
+
33
+ attrs[:jid] = Blather::JID.new('n@d/r')
34
+ attrs[:jid].must_equal 'n@d/r'
35
+ end
36
+
37
+ it 'removes an attribute when set to nil' do
38
+ attrs = Nokogiri::XML::Node.new('foo', @doc)
39
+ attrs['foo'] = 'bar'
40
+
41
+ attrs['foo'].must_equal 'bar'
42
+ attrs['foo'] = nil
43
+ attrs['foo'].must_be_nil
44
+ end
45
+
46
+ it 'allows attribute values to change' do
47
+ attrs = Nokogiri::XML::Node.new('foo', @doc)
48
+ attrs['foo'] = 'bar'
49
+
50
+ attrs['foo'].must_equal 'bar'
51
+ attrs['foo'] = 'baz'
52
+ attrs['foo'].must_equal 'baz'
53
+ end
54
+
55
+ it 'allows symbols as the path in #xpath' do
56
+ node = Nokogiri::XML::Node.new('foo', @doc)
57
+ node.must_respond_to :find
58
+ @doc.root = node
59
+ @doc.xpath(:foo).first.wont_be_nil
60
+ @doc.xpath(:foo).first.must_equal @doc.xpath('/foo').first
61
+ end
62
+
63
+ it 'allows symbols as namespace names in #xpath' do
64
+ node = Nokogiri::XML::Node.new('foo', @doc)
65
+ node.namespace = node.add_namespace('bar', 'baz')
66
+ @doc.root = node
67
+ node.xpath('/bar:foo', :bar => 'baz').first.wont_be_nil
68
+ end
69
+
70
+ it 'aliases #xpath to #find' do
71
+ node = Nokogiri::XML::Node.new('foo', @doc)
72
+ node.must_respond_to :find
73
+ @doc.root = node
74
+ node.find('/foo').first.wont_be_nil
75
+ end
76
+
77
+ it 'has a helper function #find_first' do
78
+ node = Nokogiri::XML::Node.new('foo', @doc)
79
+ node.must_respond_to :find
80
+ @doc.root = node
81
+ node.find_first('/foo').must_equal node.find('/foo').first
82
+ end
83
+ end
@@ -1,18 +1,18 @@
1
1
  require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
2
2
 
3
3
  def sasl_error_node(err_name = 'aborted')
4
- node = XMPPNode.new 'failure'
5
- node.namespace = 'urn:ietf:params:xml:ns:xmpp-sasl'
4
+ node = Blather::XMPPNode.new 'failure'
5
+ node.namespace = Blather::SASLError::SASL_ERR_NS
6
6
 
7
- node << XMPPNode.new(err_name)
7
+ node << Blather::XMPPNode.new(err_name, node.document)
8
8
  node
9
9
  end
10
10
 
11
- describe 'Blather::SASLError' do
11
+ describe Blather::SASLError do
12
12
  it 'can import a node' do
13
- SASLError.must_respond_to :import
14
- e = SASLError.import sasl_error_node
15
- e.must_be_kind_of SASLError
13
+ Blather::SASLError.must_respond_to :import
14
+ e = Blather::SASLError.import sasl_error_node
15
+ e.must_be_kind_of Blather::SASLError
16
16
  end
17
17
 
18
18
  describe 'each XMPP SASL error type' do
@@ -25,7 +25,7 @@ describe 'Blather::SASLError' do
25
25
  temporary-auth-failure
26
26
  ].each do |error_type|
27
27
  it "handles the name for #{error_type}" do
28
- e = SASLError.import sasl_error_node(error_type)
28
+ e = Blather::SASLError.import sasl_error_node(error_type)
29
29
  e.name.must_equal error_type.gsub('-','_').to_sym
30
30
  end
31
31
  end