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.
- data/LICENSE +1 -1
- data/README.rdoc +41 -12
- data/examples/echo.rb +1 -1
- data/examples/execute.rb +0 -5
- data/examples/pubsub/cli.rb +64 -0
- data/examples/pubsub/ping_pong.rb +18 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +19 -13
- data/lib/blather/client/dsl/pubsub.rb +133 -0
- data/lib/blather/client/dsl.rb +16 -0
- data/lib/blather/client.rb +1 -1
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
- data/lib/blather/core_ext/active_support.rb +1 -117
- data/lib/blather/core_ext/nokogiri.rb +35 -0
- data/lib/blather/errors/sasl_error.rb +3 -1
- data/lib/blather/errors/stanza_error.rb +10 -17
- data/lib/blather/errors/stream_error.rb +11 -14
- data/lib/blather/errors.rb +3 -20
- data/lib/blather/jid.rb +1 -0
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +6 -1
- data/lib/blather/stanza/disco/disco_info.rb +45 -33
- data/lib/blather/stanza/disco/disco_items.rb +32 -21
- data/lib/blather/stanza/disco.rb +7 -1
- data/lib/blather/stanza/iq/query.rb +16 -8
- data/lib/blather/stanza/iq/roster.rb +33 -22
- data/lib/blather/stanza/iq.rb +13 -8
- data/lib/blather/stanza/message.rb +20 -31
- data/lib/blather/stanza/presence/status.rb +13 -21
- data/lib/blather/stanza/presence/subscription.rb +11 -16
- data/lib/blather/stanza/presence.rb +3 -5
- data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
- data/lib/blather/stanza/pubsub/create.rb +43 -0
- data/lib/blather/stanza/pubsub/errors.rb +9 -0
- data/lib/blather/stanza/pubsub/event.rb +77 -0
- data/lib/blather/stanza/pubsub/items.rb +63 -0
- data/lib/blather/stanza/pubsub/publish.rb +58 -0
- data/lib/blather/stanza/pubsub/retract.rb +53 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
- data/lib/blather/stanza/pubsub/subscription.rb +66 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
- data/lib/blather/stanza/pubsub.rb +63 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
- data/lib/blather/stanza/pubsub_owner.rb +41 -0
- data/lib/blather/stanza.rb +35 -18
- data/lib/blather/stream/client.rb +1 -2
- data/lib/blather/stream/component.rb +9 -5
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +70 -46
- data/lib/blather/stream.rb +76 -168
- data/lib/blather/xmpp_node.rb +113 -52
- data/lib/blather.rb +35 -12
- data/spec/blather/client/client_spec.rb +44 -58
- data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
- data/spec/blather/client/dsl_spec.rb +19 -6
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +8 -8
- data/spec/blather/errors/stanza_error_spec.rb +25 -33
- data/spec/blather/errors/stream_error_spec.rb +21 -16
- data/spec/blather/errors_spec.rb +4 -11
- data/spec/blather/jid_spec.rb +31 -30
- data/spec/blather/roster_item_spec.rb +34 -23
- data/spec/blather/roster_spec.rb +27 -12
- data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
- data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
- data/spec/blather/stanza/iq/query_spec.rb +34 -11
- data/spec/blather/stanza/iq/roster_spec.rb +47 -30
- data/spec/blather/stanza/iq_spec.rb +19 -14
- data/spec/blather/stanza/message_spec.rb +30 -17
- data/spec/blather/stanza/presence/status_spec.rb +43 -20
- data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
- data/spec/blather/stanza/presence_spec.rb +34 -21
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +62 -0
- data/spec/blather/stanza_spec.rb +53 -38
- data/spec/blather/stream/client_spec.rb +231 -88
- data/spec/blather/stream/component_spec.rb +14 -5
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +192 -96
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +5 -4
- metadata +53 -17
- data/Rakefile +0 -139
- data/ext/extconf.rb +0 -65
- data/ext/push_parser.c +0 -209
- data/lib/blather/core_ext/libxml.rb +0 -28
- data/lib/blather/stream/resource.rb +0 -48
- data/lib/blather/stream/session.rb +0 -36
- data/lib/blather/stream/stream_handler.rb +0 -39
- data/lib/blather/stream/tls.rb +0 -33
- data/spec/blather/core_ext/libxml_spec.rb +0 -58
@@ -1,6 +1,7 @@
|
|
1
|
+
require 'resolv'
|
1
2
|
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
2
3
|
|
3
|
-
describe
|
4
|
+
describe Blather::Stream::Client do
|
4
5
|
class MockServer; end
|
5
6
|
module ServerMock
|
6
7
|
def receive_data(data)
|
@@ -12,44 +13,102 @@ describe 'Blather::Stream::Client' do
|
|
12
13
|
def mocked_server(times = nil, &block)
|
13
14
|
@client ||= mock()
|
14
15
|
@client.stubs(:unbind) unless @client.respond_to?(:unbind)
|
16
|
+
@client.stubs(:post_init) unless @client.respond_to?(:post_init)
|
15
17
|
@client.stubs(:jid=) unless @client.respond_to?(:jid=)
|
16
18
|
|
17
19
|
MockServer.any_instance.expects(:receive_data).send(*(times ? [:times, times] : [:at_least, 1])).with &block
|
18
20
|
EventMachine::run {
|
21
|
+
EM.add_timer(0.5) { EM.stop if EM.reactor_running? }
|
22
|
+
|
19
23
|
# Mocked server
|
20
24
|
EventMachine::start_server '127.0.0.1', 12345, ServerMock
|
21
25
|
|
22
|
-
# Stream connection
|
23
|
-
EM.connect('127.0.0.1', 12345, Stream::Client, @client, @jid || JID.new('n@d/r'), 'pass') { |c| @stream = c }
|
26
|
+
# Blather::Stream connection
|
27
|
+
EM.connect('127.0.0.1', 12345, Blather::Stream::Client, @client, @jid || Blather::JID.new('n@d/r'), 'pass') { |c| @stream = c }
|
24
28
|
}
|
25
29
|
end
|
26
30
|
|
31
|
+
|
27
32
|
it 'can be started' do
|
28
33
|
client = mock()
|
29
34
|
params = [client, 'n@d/r', 'pass', 'host', 1234]
|
30
35
|
EM.expects(:connect).with do |*parms|
|
31
|
-
parms[0]
|
32
|
-
parms[1]
|
33
|
-
parms[3]
|
34
|
-
parms[5]
|
35
|
-
parms[4]
|
36
|
+
parms[0].must_equal 'host'
|
37
|
+
parms[1].must_equal 1234
|
38
|
+
parms[3].must_equal client
|
39
|
+
parms[5].must_equal 'pass'
|
40
|
+
parms[4].must_equal Blather::JID.new('n@d/r')
|
41
|
+
end
|
42
|
+
|
43
|
+
Blather::Stream::Client.start *params
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'attempts to find the SRV record if a host is not provided' do
|
47
|
+
dns = mock(:sort! => nil, :empty? => false)
|
48
|
+
dns.expects(:each).yields(mock({
|
49
|
+
:target => 'd',
|
50
|
+
:port => 5222
|
51
|
+
}))
|
52
|
+
Resolv::DNS.expects(:open).yields(mock(:getresources => dns))
|
53
|
+
|
54
|
+
client = Class.new
|
55
|
+
EM.expects(:connect).with do |*parms|
|
56
|
+
parms[0].must_equal 'd'
|
57
|
+
parms[1].must_equal 5222
|
58
|
+
parms[3].must_equal client
|
59
|
+
parms[5].must_equal 'pass'
|
60
|
+
parms[4].must_equal Blather::JID.new('n@d/r')
|
36
61
|
end
|
37
62
|
|
38
|
-
Stream::Client.start
|
63
|
+
Blather::Stream::Client.start client, 'n@d/r', 'pass'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'will attempt as many connections as it takes' do
|
67
|
+
dns = [mock(:target => 'd', :port => 5222), mock(:target => 'g', :port => 1234)]
|
68
|
+
dns.stubs(:sort!) #ignore sorting
|
69
|
+
Resolv::DNS.expects(:open).yields(mock(:getresources => dns))
|
70
|
+
|
71
|
+
client = Class.new
|
72
|
+
EM.expects(:connect).with do |*parms|
|
73
|
+
raise Blather::Stream::NoConnection if parms[0] == 'd'
|
74
|
+
parms[0].must_equal 'g'
|
75
|
+
parms[1].must_equal 1234
|
76
|
+
parms[3].must_equal client
|
77
|
+
parms[5].must_equal 'pass'
|
78
|
+
parms[4].must_equal Blather::JID.new('n@d/r')
|
79
|
+
end
|
80
|
+
Blather::Stream::Client.start client, 'n@d/r', 'pass'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'will not attempt to connect more often than necessary' do
|
84
|
+
dns = [mock(:target => 'd', :port => 5222), mock()]
|
85
|
+
dns.stubs(:sort!) #ignore sorting
|
86
|
+
Resolv::DNS.expects(:open).yields(mock(:getresources => dns))
|
87
|
+
|
88
|
+
client = Class.new
|
89
|
+
EM.expects(:connect).with do |*parms|
|
90
|
+
parms[0].must_equal 'd'
|
91
|
+
parms[1].must_equal 5222
|
92
|
+
parms[3].must_equal client
|
93
|
+
parms[5].must_equal 'pass'
|
94
|
+
parms[4].must_equal Blather::JID.new('n@d/r')
|
95
|
+
end
|
96
|
+
Blather::Stream::Client.start client, 'n@d/r', 'pass'
|
39
97
|
end
|
40
98
|
|
41
99
|
it 'can figure out the host to use based on the jid' do
|
42
|
-
|
43
|
-
|
100
|
+
Resolv::DNS.expects(:open).yields(mock(:getresources => mock(:empty? => true)))
|
101
|
+
client = Class.new
|
102
|
+
params = [client, 'n@d/r', 'pass', nil, 5222]
|
44
103
|
EM.expects(:connect).with do |*parms|
|
45
|
-
parms[0]
|
46
|
-
parms[1]
|
47
|
-
parms[3]
|
48
|
-
parms[5]
|
49
|
-
parms[4]
|
104
|
+
parms[0].must_equal 'd'
|
105
|
+
parms[1].must_equal 5222
|
106
|
+
parms[3].must_equal client
|
107
|
+
parms[5].must_equal 'pass'
|
108
|
+
parms[4].must_equal Blather::JID.new('n@d/r')
|
50
109
|
end
|
51
110
|
|
52
|
-
Stream::Client.start client, 'n@d/r', 'pass'
|
111
|
+
Blather::Stream::Client.start client, 'n@d/r', 'pass'
|
53
112
|
end
|
54
113
|
|
55
114
|
it 'starts the stream once the connection is complete' do
|
@@ -60,7 +119,7 @@ describe 'Blather::Stream::Client' do
|
|
60
119
|
@client = mock()
|
61
120
|
@client.expects(:receive_data).with do |n|
|
62
121
|
EM.stop
|
63
|
-
n.
|
122
|
+
n.must_be_kind_of Blather::Stanza::Message
|
64
123
|
end
|
65
124
|
|
66
125
|
mocked_server(1) do |val, server|
|
@@ -70,7 +129,7 @@ describe 'Blather::Stream::Client' do
|
|
70
129
|
end
|
71
130
|
end
|
72
131
|
|
73
|
-
it 'puts itself in the stopped state and calls @client.
|
132
|
+
it 'puts itself in the stopped state and calls @client.unbind when unbound' do
|
74
133
|
@client = mock()
|
75
134
|
@client.expects(:unbind).at_least_once
|
76
135
|
|
@@ -95,7 +154,6 @@ describe 'Blather::Stream::Client' do
|
|
95
154
|
it 'will be in the negotiating state during feature negotiations' do
|
96
155
|
state = nil
|
97
156
|
@client = mock()
|
98
|
-
@client.stubs(:post_init)
|
99
157
|
@client.expects(:receive_data).with do |n|
|
100
158
|
EM.stop
|
101
159
|
state.must_equal(:negotiated) && @stream.negotiating?.must_equal(false)
|
@@ -111,7 +169,7 @@ describe 'Blather::Stream::Client' do
|
|
111
169
|
|
112
170
|
when :started
|
113
171
|
state = :negotiated
|
114
|
-
@stream.negotiating?.must_equal
|
172
|
+
@stream.negotiating?.must_equal true
|
115
173
|
server.send_data "<iq from='d' type='result' id='#{val[/id="([^"]+)"/,1]}' />"
|
116
174
|
server.send_data "<message to='a@b/c' from='d@e/f' type='chat' xml:lang='en'><body>Message!</body></message>"
|
117
175
|
true
|
@@ -186,13 +244,36 @@ describe 'Blather::Stream::Client' do
|
|
186
244
|
end
|
187
245
|
end
|
188
246
|
|
247
|
+
it 'skips features it is unable to handle' do
|
248
|
+
state = nil
|
249
|
+
mocked_server() do |val, server|
|
250
|
+
case state
|
251
|
+
when nil
|
252
|
+
state = :started
|
253
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
254
|
+
server.send_data "<stream:features><auth xmlns='http://jabber.org/features/iq-auth'/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' /></stream:features>"
|
255
|
+
val.must_match(/stream:stream/)
|
256
|
+
|
257
|
+
when :started
|
258
|
+
EM.stop
|
259
|
+
val.must_match(/starttls/)
|
260
|
+
|
261
|
+
else
|
262
|
+
EM.stop
|
263
|
+
false
|
264
|
+
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
189
269
|
it 'starts TLS when asked' do
|
190
270
|
state = nil
|
191
271
|
mocked_server(3) do |val, server|
|
192
272
|
case state
|
193
273
|
when nil
|
194
274
|
state = :started
|
195
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
|
275
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
276
|
+
server.send_data "<stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' /></stream:features>"
|
196
277
|
val.must_match(/stream:stream/)
|
197
278
|
|
198
279
|
when :started
|
@@ -216,7 +297,7 @@ describe 'Blather::Stream::Client' do
|
|
216
297
|
it 'will fail if TLS negotiation fails' do
|
217
298
|
state = nil
|
218
299
|
@client = mock()
|
219
|
-
@client.expects(:receive_data).with { |v| v.must_be_kind_of TLSFailure }
|
300
|
+
@client.expects(:receive_data).with { |v| v.must_be_kind_of Blather::Stream::TLS::TLSFailure }
|
220
301
|
mocked_server(3) do |val, server|
|
221
302
|
case state
|
222
303
|
when nil
|
@@ -246,14 +327,14 @@ describe 'Blather::Stream::Client' do
|
|
246
327
|
state = nil
|
247
328
|
@client = mock()
|
248
329
|
@client.expects(:receive_data).with do |v|
|
249
|
-
v.must_be_kind_of
|
250
|
-
v.node.element_name.must_equal 'foo-bar'
|
330
|
+
v.must_be_kind_of Blather::Stream::TLS::TLSFailure
|
251
331
|
end
|
252
332
|
mocked_server(3) do |val, server|
|
253
333
|
case state
|
254
334
|
when nil
|
255
335
|
state = :started
|
256
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
|
336
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
337
|
+
server.send_data "<stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' /></stream:features>"
|
257
338
|
val.must_match(/stream:stream/)
|
258
339
|
|
259
340
|
when :started
|
@@ -368,9 +449,9 @@ describe 'Blather::Stream::Client' do
|
|
368
449
|
end
|
369
450
|
end
|
370
451
|
|
371
|
-
it 'connects via ANONYMOUS if the JID has a blank node' do
|
452
|
+
it 'connects via ANONYMOUS if the Blather::JID has a blank node' do
|
372
453
|
state = nil
|
373
|
-
@jid = JID.new '@d'
|
454
|
+
@jid = Blather::JID.new '@d'
|
374
455
|
|
375
456
|
mocked_server(3) do |val, server|
|
376
457
|
case state
|
@@ -397,11 +478,37 @@ describe 'Blather::Stream::Client' do
|
|
397
478
|
end
|
398
479
|
end
|
399
480
|
|
481
|
+
it 'fails if asked to connect via ANONYMOUS but the server does not support it' do
|
482
|
+
state = nil
|
483
|
+
@jid = Blather::JID.new '@d'
|
484
|
+
@client = mock()
|
485
|
+
@client.expects(:receive_data).with { |s| s.must_be_instance_of Blather::BlatherError }
|
486
|
+
|
487
|
+
mocked_server(2) do |val, server|
|
488
|
+
case state
|
489
|
+
when nil
|
490
|
+
state = :started
|
491
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
492
|
+
server.send_data "<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>"
|
493
|
+
val.must_match(/stream:stream/)
|
494
|
+
|
495
|
+
when :started
|
496
|
+
EM.stop
|
497
|
+
val.must_match(/stream:stream/)
|
498
|
+
|
499
|
+
else
|
500
|
+
EM.stop
|
501
|
+
false
|
502
|
+
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
400
507
|
it 'tries each possible mechanism until it fails completely' do
|
401
508
|
state = nil
|
402
509
|
@client = mock()
|
403
510
|
@client.expects(:receive_data).with do |n|
|
404
|
-
n.must_be_kind_of(SASLError)
|
511
|
+
n.must_be_kind_of(Blather::SASLError)
|
405
512
|
n.name.must_equal :not_authorized
|
406
513
|
end
|
407
514
|
|
@@ -409,7 +516,8 @@ describe 'Blather::Stream::Client' do
|
|
409
516
|
case state
|
410
517
|
when nil
|
411
518
|
state = :started
|
412
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
|
519
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
520
|
+
server.send_data "<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism></mechanisms></stream:features>"
|
413
521
|
val.must_match(/stream:stream/)
|
414
522
|
|
415
523
|
when :started
|
@@ -471,9 +579,37 @@ describe 'Blather::Stream::Client' do
|
|
471
579
|
end
|
472
580
|
end
|
473
581
|
|
582
|
+
it 'will ignore methods it does not understand' do
|
583
|
+
state = nil
|
584
|
+
mocked_server(3) do |val, server|
|
585
|
+
case state
|
586
|
+
when nil
|
587
|
+
state = :started
|
588
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
589
|
+
server.send_data "<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>CRAM-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>"
|
590
|
+
val.must_match(/stream:stream/)
|
591
|
+
|
592
|
+
when :started
|
593
|
+
state = :auth_sent
|
594
|
+
server.send_data "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />"
|
595
|
+
val.must_equal('<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">bkBkAG4AcGFzcw==</auth>')
|
596
|
+
|
597
|
+
when :auth_sent
|
598
|
+
EM.stop
|
599
|
+
state = :complete
|
600
|
+
val.must_match(/stream:stream/)
|
601
|
+
|
602
|
+
else
|
603
|
+
EM.stop
|
604
|
+
false
|
605
|
+
|
606
|
+
end
|
607
|
+
end
|
608
|
+
end
|
609
|
+
=begin
|
474
610
|
it 'sends client an error when an unknown mechanism is sent' do
|
475
611
|
@client = mock()
|
476
|
-
@client.expects(:receive_data).with { |v| v.must_be_kind_of(Stream::SASL::UnknownMechanism) }
|
612
|
+
@client.expects(:receive_data).with { |v| v.must_be_kind_of(Blather::Stream::SASL::UnknownMechanism) }
|
477
613
|
started = false
|
478
614
|
mocked_server(2) do |val, server|
|
479
615
|
if !started
|
@@ -489,7 +625,7 @@ describe 'Blather::Stream::Client' do
|
|
489
625
|
end
|
490
626
|
end
|
491
627
|
end
|
492
|
-
|
628
|
+
=end
|
493
629
|
%w[ aborted
|
494
630
|
incorrect-encoding
|
495
631
|
invalid-authzid
|
@@ -533,7 +669,7 @@ describe 'Blather::Stream::Client' do
|
|
533
669
|
it 'fails when an unkown node comes through during SASL negotiation' do
|
534
670
|
@client = mock()
|
535
671
|
@client.expects(:receive_data).with do |n|
|
536
|
-
n.must_be_instance_of UnknownResponse
|
672
|
+
n.must_be_instance_of Blather::UnknownResponse
|
537
673
|
n.node.element_name.must_equal 'foo-bar'
|
538
674
|
end
|
539
675
|
state = nil
|
@@ -566,13 +702,14 @@ describe 'Blather::Stream::Client' do
|
|
566
702
|
state = nil
|
567
703
|
class Client; attr_accessor :jid; end
|
568
704
|
@client = Client.new
|
569
|
-
@jid = JID.new('n@d')
|
705
|
+
@jid = Blather::JID.new('n@d')
|
570
706
|
|
571
707
|
mocked_server(3) do |val, server|
|
572
708
|
case state
|
573
709
|
when nil
|
574
710
|
state = :started
|
575
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
|
711
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
712
|
+
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
576
713
|
val.must_match(/stream:stream/)
|
577
714
|
|
578
715
|
when :started
|
@@ -584,7 +721,7 @@ describe 'Blather::Stream::Client' do
|
|
584
721
|
|
585
722
|
when :complete
|
586
723
|
EM.stop
|
587
|
-
@client.jid.must_equal JID.new('n@d/server_resource')
|
724
|
+
@client.jid.must_equal Blather::JID.new('n@d/server_resource')
|
588
725
|
|
589
726
|
else
|
590
727
|
EM.stop
|
@@ -598,7 +735,7 @@ describe 'Blather::Stream::Client' do
|
|
598
735
|
state = nil
|
599
736
|
class Client; attr_accessor :jid; end
|
600
737
|
@client = Client.new
|
601
|
-
@jid = JID.new('n@d/r')
|
738
|
+
@jid = Blather::JID.new('n@d/r')
|
602
739
|
|
603
740
|
mocked_server(3) do |val, server|
|
604
741
|
case state
|
@@ -609,14 +746,47 @@ describe 'Blather::Stream::Client' do
|
|
609
746
|
|
610
747
|
when :started
|
611
748
|
state = :complete
|
612
|
-
|
613
|
-
|
749
|
+
doc = parse_stanza val
|
750
|
+
doc.xpath('/iq/bind_ns:bind/bind_ns:resource[.="r"]', :bind_ns => Blather::Stream::Resource::BIND_NS).wont_be_empty
|
751
|
+
|
752
|
+
server.send_data "<iq type='result' id='#{doc.find_first('iq')['id']}'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>#{@jid}</jid></bind></iq>"
|
614
753
|
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
615
|
-
val.must_match(%r{<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>r</resource></bind>})
|
616
754
|
|
617
755
|
when :complete
|
618
756
|
EM.stop
|
619
|
-
@client.jid.must_equal JID.new('n@d/r')
|
757
|
+
@client.jid.must_equal Blather::JID.new('n@d/r')
|
758
|
+
|
759
|
+
else
|
760
|
+
EM.stop
|
761
|
+
false
|
762
|
+
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
it 'will error out if the bind ID mismatches' do
|
768
|
+
state = nil
|
769
|
+
@jid = Blather::JID.new('n@d')
|
770
|
+
@client = mock()
|
771
|
+
|
772
|
+
mocked_server(3) do |val, server|
|
773
|
+
case state
|
774
|
+
when nil
|
775
|
+
state = :started
|
776
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
777
|
+
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
778
|
+
val.must_match(/stream:stream/)
|
779
|
+
|
780
|
+
when :started
|
781
|
+
state = :complete
|
782
|
+
val =~ %r{<iq[^>]+id="([^"]+)"}
|
783
|
+
@client.expects(:receive_data).with("BIND result ID mismatch. Expected: #{$1}. Received: #{$1}-bad")
|
784
|
+
server.send_data "<iq type='result' id='#{$1}-bad'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>#{@jid}/server_resource</jid></bind></iq>"
|
785
|
+
val.must_match(%r{<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"\s?/>})
|
786
|
+
|
787
|
+
when :complete
|
788
|
+
EM.stop
|
789
|
+
true
|
620
790
|
|
621
791
|
else
|
622
792
|
EM.stop
|
@@ -641,9 +811,9 @@ describe 'Blather::Stream::Client' do
|
|
641
811
|
|
642
812
|
when :started
|
643
813
|
state = :complete
|
644
|
-
|
645
|
-
|
646
|
-
|
814
|
+
doc = parse_stanza val
|
815
|
+
doc.xpath('/iq/bind_ns:bind/bind_ns:resource[.="r"]', :bind_ns => Blather::Stream::Resource::BIND_NS).wont_be_empty
|
816
|
+
server.send_data "<iq type='error' id='#{doc.find_first('iq')['id']}'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>r</resource></bind><error type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>"
|
647
817
|
|
648
818
|
when :complete
|
649
819
|
EM.stop
|
@@ -661,21 +831,22 @@ describe 'Blather::Stream::Client' do
|
|
661
831
|
state = nil
|
662
832
|
@client = mock()
|
663
833
|
@client.expects(:receive_data).with do |n|
|
664
|
-
n.must_be_instance_of UnknownResponse
|
834
|
+
n.must_be_instance_of Blather::UnknownResponse
|
665
835
|
n.node.element_name.must_equal 'foo-bar'
|
666
836
|
end
|
667
837
|
mocked_server(3) do |val, server|
|
668
838
|
case state
|
669
839
|
when nil
|
670
840
|
state = :started
|
671
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
|
841
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
842
|
+
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
672
843
|
val.must_match(/stream:stream/)
|
673
844
|
|
674
845
|
when :started
|
675
846
|
state = :complete
|
676
|
-
|
847
|
+
doc = parse_stanza val
|
848
|
+
doc.xpath('/iq/bind_ns:bind/bind_ns:resource[.="r"]', :bind_ns => Blather::Stream::Resource::BIND_NS).wont_be_empty
|
677
849
|
server.send_data "<foo-bar />"
|
678
|
-
val.must_match(%r{<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>r</resource></bind>})
|
679
850
|
|
680
851
|
when :complete
|
681
852
|
EM.stop
|
@@ -704,9 +875,10 @@ describe 'Blather::Stream::Client' do
|
|
704
875
|
|
705
876
|
when :started
|
706
877
|
state = :completed
|
707
|
-
|
878
|
+
doc = parse_stanza val
|
879
|
+
doc.find('/iq[@type="set" and @to="d"]/sess_ns:session', :sess_ns => Blather::Stream::Session::SESSION_NS).wont_be_empty
|
880
|
+
server.send_data "<iq from='d' type='result' id='#{doc.find_first('iq')['id']}' />"
|
708
881
|
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
709
|
-
val.must_match(%r{<iq id="[^"]+" type="set" to="d"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"\s?/></iq>})
|
710
882
|
|
711
883
|
when :completed
|
712
884
|
EM.stop
|
@@ -736,8 +908,9 @@ describe 'Blather::Stream::Client' do
|
|
736
908
|
|
737
909
|
when :started
|
738
910
|
state = :completed
|
739
|
-
|
740
|
-
|
911
|
+
doc = parse_stanza val
|
912
|
+
doc.find('/iq[@type="set" and @to="d"]/sess_ns:session', :sess_ns => Blather::Stream::Session::SESSION_NS).wont_be_empty
|
913
|
+
server.send_data "<iq from='d' type='error' id='#{doc.find_first('iq')['id']}'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><error type='wait'><internal-server-error xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>"
|
741
914
|
|
742
915
|
when :completed
|
743
916
|
EM.stop
|
@@ -755,7 +928,7 @@ describe 'Blather::Stream::Client' do
|
|
755
928
|
state = nil
|
756
929
|
@client = mock()
|
757
930
|
@client.expects(:receive_data).with do |n|
|
758
|
-
n.must_be_instance_of UnknownResponse
|
931
|
+
n.must_be_instance_of Blather::UnknownResponse
|
759
932
|
n.node.element_name.must_equal 'foo-bar'
|
760
933
|
end
|
761
934
|
mocked_server(3) do |val, server|
|
@@ -768,8 +941,9 @@ describe 'Blather::Stream::Client' do
|
|
768
941
|
|
769
942
|
when :started
|
770
943
|
state = :completed
|
944
|
+
doc = parse_stanza val
|
945
|
+
doc.find('/iq[@type="set" and @to="d"]/sess_ns:session', :sess_ns => Blather::Stream::Session::SESSION_NS).wont_be_empty
|
771
946
|
server.send_data '<foo-bar />'
|
772
|
-
val.must_match(%r{<iq id="[^"]+" type="set" to="d"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"\s?/></iq>})
|
773
947
|
|
774
948
|
when :completed
|
775
949
|
EM.stop
|
@@ -783,42 +957,10 @@ describe 'Blather::Stream::Client' do
|
|
783
957
|
end
|
784
958
|
end
|
785
959
|
|
786
|
-
it 'sends
|
787
|
-
@client = mock()
|
788
|
-
@client.expects(:receive_data).with do |v|
|
789
|
-
EM.stop
|
790
|
-
v.must_be_kind_of ParseWarning
|
791
|
-
v.message.must_match(/vcard\-temp/)
|
792
|
-
end
|
793
|
-
state = nil
|
794
|
-
mocked_server(2) do |val, server|
|
795
|
-
case state
|
796
|
-
when nil
|
797
|
-
state = :started
|
798
|
-
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>"
|
799
|
-
server.send_data "<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind' /></stream:features>"
|
800
|
-
val.must_match(/stream:stream/)
|
801
|
-
|
802
|
-
when :started
|
803
|
-
server.send_data <<-XML
|
804
|
-
<iq xmlns="jabber:client" to="utterance.localhost" type="get" id="2590">
|
805
|
-
<vCard xmlns="vcard-temp" />
|
806
|
-
</iq>
|
807
|
-
XML
|
808
|
-
true
|
809
|
-
|
810
|
-
else
|
811
|
-
EM.stop
|
812
|
-
false
|
813
|
-
|
814
|
-
end
|
815
|
-
end
|
816
|
-
end
|
817
|
-
|
818
|
-
it 'sends client an error on parse error' do
|
960
|
+
it 'sends client an error and reply to the server on parse error' do
|
819
961
|
@client = mock()
|
820
962
|
@client.expects(:receive_data).with do |v|
|
821
|
-
v.must_be_kind_of ParseError
|
963
|
+
v.must_be_kind_of Blather::ParseError
|
822
964
|
v.message.must_match(/generate\-parse\-error/)
|
823
965
|
end
|
824
966
|
state = nil
|
@@ -845,4 +987,5 @@ describe 'Blather::Stream::Client' do
|
|
845
987
|
end
|
846
988
|
end
|
847
989
|
end
|
990
|
+
|
848
991
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Blather::Stream::Component do
|
4
4
|
class MockServer; end
|
5
5
|
module ServerMock
|
6
6
|
def receive_data(data)
|
@@ -19,8 +19,8 @@ describe 'Blather::Stream::Component' do
|
|
19
19
|
# Mocked server
|
20
20
|
EventMachine::start_server '127.0.0.1', 12345, ServerMock
|
21
21
|
|
22
|
-
# Stream connection
|
23
|
-
EM.connect('127.0.0.1', 12345, Stream::Component, @client, @jid || 'comp.id', 'secret') { |c| @stream = c }
|
22
|
+
# Blather::Stream connection
|
23
|
+
EM.connect('127.0.0.1', 12345, Blather::Stream::Component, @client, @jid || 'comp.id', 'secret') { |c| @stream = c }
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
@@ -34,7 +34,7 @@ describe 'Blather::Stream::Component' do
|
|
34
34
|
parms[4] == 'comp.id'
|
35
35
|
end
|
36
36
|
|
37
|
-
Stream::Component.start *params
|
37
|
+
Blather::Stream::Component.start *params
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'shakes hands with the server' do
|
@@ -63,7 +63,7 @@ describe 'Blather::Stream::Component' do
|
|
63
63
|
@client = mock(:post_init)
|
64
64
|
@client.expects(:receive_data).with do |n|
|
65
65
|
EM.stop
|
66
|
-
n.kind_of?
|
66
|
+
n.kind_of? Blather::XMPPNode
|
67
67
|
end
|
68
68
|
|
69
69
|
state = nil
|
@@ -83,4 +83,13 @@ describe 'Blather::Stream::Component' do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
it 'sends stanzas to the wire with ensuring from is set' do
|
87
|
+
client = mock()
|
88
|
+
client.stubs(:jid)
|
89
|
+
client.stubs(:jid=)
|
90
|
+
msg = Blather::Stanza::Message.new 'to@jid.com', 'body'
|
91
|
+
comp = Blather::Stream::Component.new nil, client, 'jid.com', 'pass'
|
92
|
+
comp.expects(:send_data).with { |s| s.must_match(/^<message[^>]*from="jid\.com"/) }
|
93
|
+
comp.send msg
|
94
|
+
end
|
86
95
|
end
|