blather 0.7.1 → 0.8.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/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/blather.gemspec +3 -2
- data/lib/blather.rb +1 -0
- data/lib/blather/client/dsl.rb +22 -2
- data/lib/blather/client/dsl/pubsub.rb +3 -1
- data/lib/blather/stanza/presence.rb +1 -1
- data/lib/blather/stanza/presence/status.rb +5 -13
- data/lib/blather/stream/features.rb +17 -1
- data/lib/blather/stream/features/register.rb +38 -0
- data/lib/blather/stream/parser.rb +1 -1
- data/lib/blather/version.rb +1 -1
- data/spec/blather/client/client_spec.rb +1 -1
- data/spec/blather/client/dsl/pubsub_spec.rb +20 -0
- data/spec/blather/client/dsl_spec.rb +23 -3
- data/spec/blather/stanza/presence/subscription_spec.rb +2 -4
- data/spec/blather/stream/client_spec.rb +54 -0
- data/spec/blather/stream/parser_spec.rb +45 -48
- data/spec/spec_helper.rb +1 -0
- metadata +26 -9
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# [develop](https://github.com/sprsquish/blather/compare/master...develop)
|
2
2
|
|
3
|
+
# [v0.8.0](https://github.com/sprsquish/blather/compare/v0.7.1...v0.8.0) - [2012-07-09](https://rubygems.org/gems/blather/versions/0.8.0)
|
4
|
+
* Feature(jmkeys): DSL methods for joining and sending messages to MUC rooms
|
5
|
+
* Feature(jackhong): Inband registration support
|
6
|
+
* Bugfix(benlangfeld): Ensure that presence nodes which are both status and subscription may be responded to
|
7
|
+
* Bugfix(benlangfeld): A whole bunch of JRuby fixes
|
8
|
+
|
3
9
|
# [v0.7.1](https://github.com/sprsquish/blather/compare/v0.7.0...v0.7.1) - [2012-04-29](https://rubygems.org/gems/blather/versions/0.7.1)
|
4
10
|
* Documentation updates
|
5
11
|
* Bugfix(benlangfeld): Relax Nokogiri dependency to allow 1.5
|
data/README.md
CHANGED
data/blather.gemspec
CHANGED
@@ -34,9 +34,9 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.extra_rdoc_files = %w{LICENSE README.md}
|
35
35
|
|
36
36
|
s.add_dependency "eventmachine", [">= 0.12.6"]
|
37
|
-
s.add_dependency "nokogiri", ["~> 1.
|
37
|
+
s.add_dependency "nokogiri", ["~> 1.5.5"]
|
38
38
|
s.add_dependency "niceogiri", ["~> 1.0"]
|
39
|
-
s.add_dependency "activesupport", [">= 3.
|
39
|
+
s.add_dependency "activesupport", [">= 2.3.11"]
|
40
40
|
s.add_dependency "girl_friday"
|
41
41
|
|
42
42
|
s.add_development_dependency "bundler", ["~> 1.0"]
|
@@ -47,4 +47,5 @@ Gem::Specification.new do |s|
|
|
47
47
|
s.add_development_dependency "yard", ["~> 0.6.1"]
|
48
48
|
s.add_development_dependency "jruby-openssl", ["~> 0.7.4"] if jruby?
|
49
49
|
s.add_development_dependency "bluecloth" unless jruby? || rbx?
|
50
|
+
s.add_development_dependency "countdownlatch"
|
50
51
|
end
|
data/lib/blather.rb
CHANGED
data/lib/blather/client/dsl.rb
CHANGED
@@ -206,12 +206,32 @@ module Blather
|
|
206
206
|
client.write stanza
|
207
207
|
end
|
208
208
|
|
209
|
+
# Helper method to join a MUC room
|
210
|
+
#
|
211
|
+
# @overload join(room_jid, nickname)
|
212
|
+
# @param [Blather::JID, #to_s] room the JID of the room to join
|
213
|
+
# @param [#to_s] nickname the nickname to join the room as
|
214
|
+
# @overload join(room_jid, nickname)
|
215
|
+
# @param [#to_s] room the name of the room to join
|
216
|
+
# @param [Blather::JID, #to_s] service the service domain the room is hosted at
|
217
|
+
# @param [#to_s] nickname the nickname to join the room as
|
218
|
+
def join(room, service, nickname = nil)
|
219
|
+
join = Blather::Stanza::Presence::MUC.new
|
220
|
+
join.to = if nickname
|
221
|
+
"#{room}@#{service}/#{nickname}"
|
222
|
+
else
|
223
|
+
"#{room}/#{service}"
|
224
|
+
end
|
225
|
+
client.write join
|
226
|
+
end
|
227
|
+
|
209
228
|
# Helper method to make sending basic messages easier
|
210
229
|
#
|
211
230
|
# @param [Blather::JID, #to_s] to the JID of the message recipient
|
212
231
|
# @param [#to_s] msg the message to send
|
213
|
-
|
214
|
-
|
232
|
+
# @param [#to_sym] the stanza method to use
|
233
|
+
def say(to, msg, using = :chat)
|
234
|
+
client.write Blather::Stanza::Message.new(to, msg, using)
|
215
235
|
end
|
216
236
|
|
217
237
|
# The JID according to the server
|
@@ -121,9 +121,11 @@ module DSL
|
|
121
121
|
#
|
122
122
|
# @param [#to_s] node the node to create
|
123
123
|
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
124
|
+
# @param [optional, Blather::Stanza::X] configuration the additional configuration to be set to created node
|
124
125
|
# @yield [Blather::Stanza] stanza the reply stanza
|
125
|
-
def create(node, host = nil)
|
126
|
+
def create(node, host = nil, configuration = nil)
|
126
127
|
stanza = Stanza::PubSub::Create.new(:set, send_to(host), node)
|
128
|
+
stanza.configure_node << configuration if configuration
|
127
129
|
request(stanza) { |n| yield n if block_given? }
|
128
130
|
end
|
129
131
|
|
@@ -77,6 +77,7 @@ class Presence
|
|
77
77
|
class Status < Presence
|
78
78
|
# @private
|
79
79
|
VALID_STATES = [:away, :chat, :dnd, :xa].freeze
|
80
|
+
VALID_TYPES = [:unavailable].freeze
|
80
81
|
|
81
82
|
include Comparable
|
82
83
|
|
@@ -130,17 +131,6 @@ class Presence
|
|
130
131
|
self.state == :xa
|
131
132
|
end
|
132
133
|
|
133
|
-
# Set the type attribute
|
134
|
-
# Ensures type is nil or :unavailable
|
135
|
-
#
|
136
|
-
# @param [<:unavailable, nil>] type the type
|
137
|
-
def type=(type)
|
138
|
-
if type && type.to_sym != :unavailable
|
139
|
-
raise ArgumentError, "Invalid type (#{type}). Must be nil or unavailable"
|
140
|
-
end
|
141
|
-
super
|
142
|
-
end
|
143
|
-
|
144
134
|
# Set the state
|
145
135
|
# Ensure state is one of :available, :away, :chat, :dnd, :xa or nil
|
146
136
|
#
|
@@ -203,8 +193,10 @@ class Presence
|
|
203
193
|
# @param [Blather::Stanza::Presence::Status] o
|
204
194
|
# @return [true,false]
|
205
195
|
def <=>(o)
|
206
|
-
|
207
|
-
|
196
|
+
if self.from || o.from
|
197
|
+
unless self.from.stripped == o.from.stripped
|
198
|
+
raise ArgumentError, "Cannot compare status from different JIDs: #{[self.from, o.from].inspect}"
|
199
|
+
end
|
208
200
|
end
|
209
201
|
|
210
202
|
if (self.type.nil? && o.type.nil?) || (!self.type.nil? && !o.type.nil?)
|
@@ -31,7 +31,19 @@ class Stream
|
|
31
31
|
@idx = @idx ? @idx+1 : 0
|
32
32
|
if stanza = @features.children[@idx]
|
33
33
|
if stanza.namespaces['xmlns'] && (klass = self.class.from_namespace(stanza.namespaces['xmlns']))
|
34
|
-
@feature = klass.new
|
34
|
+
@feature = klass.new(
|
35
|
+
@stream,
|
36
|
+
proc {
|
37
|
+
if (klass == Blather::Stream::Register && stanza = feature?(:mechanisms))
|
38
|
+
@idx = @features.children.index(stanza)
|
39
|
+
@feature = Blather::Stream::SASL.new @stream, proc { next! }, @fail
|
40
|
+
@feature.receive_data stanza
|
41
|
+
else
|
42
|
+
next!
|
43
|
+
end
|
44
|
+
},
|
45
|
+
(klass == Blather::Stream::SASL && feature?(:register)) ? proc { next! } : @fail
|
46
|
+
)
|
35
47
|
@feature.receive_data stanza
|
36
48
|
else
|
37
49
|
next!
|
@@ -48,6 +60,10 @@ class Stream
|
|
48
60
|
def fail!(msg)
|
49
61
|
@fail.call msg
|
50
62
|
end
|
63
|
+
|
64
|
+
def feature?(feature)
|
65
|
+
@features && @features.children.find { |v| v.element_name == feature.to_s }
|
66
|
+
end
|
51
67
|
end
|
52
68
|
|
53
69
|
end #Stream
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Blather
|
2
|
+
class Stream
|
3
|
+
class Register < Features
|
4
|
+
REGISTER_NS = "http://jabber.org/features/iq-register".freeze
|
5
|
+
|
6
|
+
register REGISTER_NS
|
7
|
+
|
8
|
+
def initialize(stream, succeed, fail)
|
9
|
+
super
|
10
|
+
@jid = @stream.jid
|
11
|
+
@pass = @stream.password
|
12
|
+
end
|
13
|
+
|
14
|
+
def receive_data(stanza)
|
15
|
+
error_node = stanza.xpath("//error").first
|
16
|
+
|
17
|
+
if error_node
|
18
|
+
fail!(BlatherError.new(stanza))
|
19
|
+
elsif stanza['type'] == 'result' && (stanza.content.empty? || stanza.children.find { |v| v.element_name == "query" })
|
20
|
+
succeed!
|
21
|
+
else
|
22
|
+
@stream.send register_query
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def register_query
|
27
|
+
node = Blather::Stanza::Iq::Query.new(:set)
|
28
|
+
query_node = node.xpath('//query').first
|
29
|
+
query_node['xmlns'] = 'jabber:iq:register'
|
30
|
+
Nokogiri::XML::Builder.with(query_node) do |xml|
|
31
|
+
xml.username @jid.node
|
32
|
+
xml.password @pass
|
33
|
+
end
|
34
|
+
node
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -48,7 +48,7 @@ class Stream
|
|
48
48
|
@namespaces[[prefix, uri]] ||= node.add_namespace(prefix, uri) if prefix && !ns_keys.include?(prefix)
|
49
49
|
node.namespace = @namespaces[[prefix, uri]]
|
50
50
|
|
51
|
-
|
51
|
+
unless @receiver.stopped?
|
52
52
|
@current << node if @current
|
53
53
|
@current = node
|
54
54
|
end
|
data/lib/blather/version.rb
CHANGED
@@ -682,6 +682,6 @@ describe 'Blather::Client::Caps' do
|
|
682
682
|
http://jabber.org/protocol/disco#items
|
683
683
|
http://jabber.org/protocol/muc
|
684
684
|
}
|
685
|
-
@caps.c.
|
685
|
+
Nokogiri::XML(@caps.c.to_xml).to_s.should == Nokogiri::XML("<presence><c xmlns=\"http://jabber.org/protocol/caps\" hash=\"sha-1\" node=\"http://code.google.com/p/exodus\" ver=\"QgayPKawpkPSDYmwT/WM94uAlu0=\"/></presence>").to_s
|
686
686
|
end
|
687
687
|
end
|
@@ -268,6 +268,26 @@ describe Blather::DSL::PubSub do
|
|
268
268
|
@pubsub.create '/path/to/node'
|
269
269
|
end
|
270
270
|
|
271
|
+
it 'can create a node with configuration' do
|
272
|
+
pubsub_configure = Blather::Stanza::X.new({
|
273
|
+
:type => :submit,
|
274
|
+
:fields => [
|
275
|
+
{ :var => "FORM_TYPE", :type => 'hidden', :value => "http://jabber.org/protocol/pubsub#node_config" },
|
276
|
+
{ :var => "pubsub#persist_items", :value => "0" },
|
277
|
+
{ :var => "pubsub#max_items", :value => "0" },
|
278
|
+
{ :var => "pubsub#notify_retract", :value => "0" },
|
279
|
+
{ :var => "pubsub#publish_model", :value => "open" }]
|
280
|
+
})
|
281
|
+
@client.expects(:write_with_handler).with do |n|
|
282
|
+
n.should be_instance_of Blather::Stanza::PubSub::Create
|
283
|
+
n.find("/iq[@type='set']/ns:pubsub/ns:create[@node='/path/to/node']", :ns => Blather::Stanza::PubSub.registered_ns).should_not be_empty
|
284
|
+
n.to.should == Blather::JID.new(@host)
|
285
|
+
n.type.should == :set
|
286
|
+
n.configure_node.should == pubsub_configure
|
287
|
+
end
|
288
|
+
@pubsub.create '/path/to/node', nil, pubsub_configure
|
289
|
+
end
|
290
|
+
|
271
291
|
it 'can delete a node' do
|
272
292
|
@client.expects(:write_with_handler).with do |n|
|
273
293
|
n.should be_instance_of Blather::Stanza::PubSubOwner::Delete
|
@@ -118,11 +118,31 @@ describe Blather::DSL do
|
|
118
118
|
@dsl.write_to_stream stanza
|
119
119
|
end
|
120
120
|
|
121
|
+
describe "#join" do
|
122
|
+
context "providing room and service as separate args" do
|
123
|
+
it "should join to a muc room with a specified nick" do
|
124
|
+
presence = Blather::Stanza::Presence::MUC.new
|
125
|
+
presence.to = "rabbit_hole@wonderland.lit/alice"
|
126
|
+
@client.expects(:write).with presence
|
127
|
+
@dsl.join 'rabbit_hole', 'wonderland.lit', 'alice'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "providing a room JID" do
|
132
|
+
it "should join to a muc room with a specified nick" do
|
133
|
+
presence = Blather::Stanza::Presence::MUC.new
|
134
|
+
presence.to = "rabbit_hole@wonderland.lit/alice"
|
135
|
+
@client.expects(:write).with presence
|
136
|
+
@dsl.join 'rabbit_hole@wonderland.lit', 'alice'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
121
141
|
it 'provides a "say" helper' do
|
122
|
-
to, msg = 'me@me.com', 'hello!'
|
142
|
+
to, msg, type = 'me@me.com', 'hello!', :groupchat
|
123
143
|
Blather::Stanza::Message.stubs(:next_id).returns 0
|
124
|
-
@client.expects(:write).with Blather::Stanza::Message.new(to, msg)
|
125
|
-
@dsl.say to, msg
|
144
|
+
@client.expects(:write).with Blather::Stanza::Message.new(to, msg, type)
|
145
|
+
@dsl.say to, msg, type
|
126
146
|
end
|
127
147
|
|
128
148
|
it 'provides a JID accessor' do
|
@@ -27,11 +27,9 @@ describe Blather::Stanza::Presence::Subscription do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'generates an approval using #approve!' do
|
30
|
-
|
31
|
-
sub = Blather::Stanza::Presence::Subscription.new
|
32
|
-
sub.from = jid
|
30
|
+
sub = Blather::Stanza.import Nokogiri::XML('<presence from="a@b" type="subscribe"><status/></presence>').root
|
33
31
|
sub.approve!
|
34
|
-
sub.to.should ==
|
32
|
+
sub.to.should == 'a@b'
|
35
33
|
sub.type.should == :subscribed
|
36
34
|
end
|
37
35
|
|
@@ -1033,4 +1033,58 @@ describe Blather::Stream::Client do
|
|
1033
1033
|
comp.expects(:send_data).with { |s| s.should_not match(/\n/); true }
|
1034
1034
|
comp.send msg
|
1035
1035
|
end
|
1036
|
+
|
1037
|
+
it 'tries to register if initial authentication failed but in-band registration enabled' do
|
1038
|
+
state = nil
|
1039
|
+
mocked_server(4) do |val, server|
|
1040
|
+
case state
|
1041
|
+
when nil
|
1042
|
+
state = :sasl_failed
|
1043
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
1044
|
+
server.send_data "<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>"
|
1045
|
+
server.send_data "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized /></failure>"
|
1046
|
+
val.should match(/stream:stream/)
|
1047
|
+
when :sasl_failed
|
1048
|
+
state = :registered
|
1049
|
+
server.send_data "<iq type='result'/>"
|
1050
|
+
val.should match(/jabber:iq:register/)
|
1051
|
+
when :registered
|
1052
|
+
state = :authenticated
|
1053
|
+
server.send_data "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />"
|
1054
|
+
val.should match(/mechanism="PLAIN"/)
|
1055
|
+
when :authenticated
|
1056
|
+
EM.stop
|
1057
|
+
val.should match(/stream:stream/)
|
1058
|
+
else
|
1059
|
+
EM.stop
|
1060
|
+
false
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
it 'fails when in-band registration failed' do
|
1066
|
+
state = nil
|
1067
|
+
@client = mock()
|
1068
|
+
@client.expects(:receive_data).with { |n| n.should be_instance_of Blather::BlatherError }
|
1069
|
+
mocked_server(3) do |val, server|
|
1070
|
+
case state
|
1071
|
+
when nil
|
1072
|
+
state = :sasl_failed
|
1073
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"
|
1074
|
+
server.send_data "<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>"
|
1075
|
+
server.send_data "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized /></failure>"
|
1076
|
+
val.should match(/stream:stream/)
|
1077
|
+
when :sasl_failed
|
1078
|
+
state = :registration_failed
|
1079
|
+
server.send_data "<iq type='error'><query /><error code='409' type='cancel'><conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>"
|
1080
|
+
val.should match(/jabber:iq:register/)
|
1081
|
+
when :registration_failed
|
1082
|
+
EM.stop
|
1083
|
+
val.should match(/\/stream:stream/)
|
1084
|
+
else
|
1085
|
+
EM.stop
|
1086
|
+
false
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
end
|
1036
1090
|
end
|
@@ -1,32 +1,37 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Blather::Stream::Parser do
|
4
|
-
|
5
|
-
|
4
|
+
let :client do
|
5
|
+
Class.new do
|
6
6
|
attr_reader :data
|
7
|
+
attr_accessor :latch
|
7
8
|
def stopped?; false; end
|
8
|
-
def receive(
|
9
|
+
def receive(node)
|
9
10
|
@data ||= []
|
10
|
-
@data <<
|
11
|
+
@data << node
|
12
|
+
latch.countdown!
|
11
13
|
end
|
12
14
|
end.new
|
13
|
-
@parser = Blather::Stream::Parser.new @client
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
subject { Blather::Stream::Parser.new client }
|
18
|
+
|
19
|
+
def process(*data)
|
20
|
+
client.latch = CountDownLatch.new 1
|
21
|
+
data.each { |d| subject.receive_data d }
|
22
|
+
client.latch.wait(2).should be_true
|
23
|
+
end
|
17
24
|
|
18
25
|
def check_parse(data)
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
process data
|
27
|
+
client.data.size.should == 1
|
28
|
+
client.data[0].to_s.gsub(/\n\s*/,'').should == data
|
22
29
|
end
|
23
30
|
|
24
31
|
it 'handles fragmented parsing' do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@client.data.size.should == 1
|
29
|
-
@client.data[0].to_s.gsub(/\n\s*/,'').should == '<foo><bar/></foo>'
|
32
|
+
process '<foo>', '<bar/>', '</foo>'
|
33
|
+
client.data.size.should == 1
|
34
|
+
client.data[0].to_s.gsub(/\n\s*/,'').should == '<foo><bar/></foo>'
|
30
35
|
end
|
31
36
|
|
32
37
|
it 'handles a basic example' do
|
@@ -85,71 +90,63 @@ describe Blather::Stream::Parser do
|
|
85
90
|
'<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Some special application diagnostic information...</text>',
|
86
91
|
'<special-application-condition xmlns="special:application-ns"/>',
|
87
92
|
"</error>",
|
88
|
-
"</message>"
|
93
|
+
"</message>"
|
89
94
|
]
|
90
|
-
data
|
91
|
-
|
92
|
-
|
93
|
-
|
95
|
+
process *data
|
96
|
+
client.data.size.should == 1
|
97
|
+
Nokogiri::XML(client.data[0].to_s.gsub(/\n\s*/, '')).to_s.should == Nokogiri::XML(data.join).to_s
|
98
|
+
client.data[0].xpath('//*[namespace-uri()="urn:ietf:params:xml:ns:xmpp-stanzas"]').size.should == 2
|
94
99
|
end
|
95
100
|
|
96
101
|
it 'handles not absolute namespaces' do
|
97
102
|
lambda do
|
98
|
-
|
103
|
+
process '<iq type="result" id="blather0007" to="n@d/r"><vCard xmlns="vcard-temp"/></iq>'
|
99
104
|
end.should_not raise_error
|
100
105
|
end
|
101
106
|
|
102
107
|
it 'responds with stream:stream as a separate response' do
|
103
|
-
|
104
|
-
'<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
108
|
+
process '<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
105
109
|
'<foo/>'
|
106
|
-
|
107
|
-
data.
|
108
|
-
|
109
|
-
@client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
110
|
-
@client.data[1].to_s.should == '<foo/>'
|
110
|
+
client.data.size.should == 2
|
111
|
+
client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
112
|
+
client.data[1].to_s.should == '<foo/>'
|
111
113
|
end
|
112
114
|
|
113
115
|
it 'response with stream:end when receiving </stream:stream>' do
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
process '<stream:stream xmlns:stream="http://etherx.jabber.org/streams"/>'
|
117
|
+
client.data.size.should == 2
|
118
|
+
client.data[1].to_s.should == '<stream:end xmlns:stream="http://etherx.jabber.org/streams"/>'
|
117
119
|
end
|
118
120
|
|
119
121
|
it 'raises ParseError when an error is sent' do
|
120
|
-
lambda {
|
122
|
+
lambda { process "<stream:stream>" }.should raise_error(Blather::ParseError)
|
121
123
|
end
|
122
124
|
|
123
125
|
it 'handles stream stanzas without an issue' do
|
124
|
-
|
125
|
-
'<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
126
|
+
process '<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
126
127
|
'<stream:features/>'
|
127
|
-
|
128
|
-
data.
|
129
|
-
|
130
|
-
@client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
131
|
-
@client.data[1].to_s.should == '<stream:features xmlns:stream="http://etherx.jabber.org/streams"/>'
|
128
|
+
client.data.size.should == 2
|
129
|
+
client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
130
|
+
client.data[1].to_s.should == '<stream:features xmlns:stream="http://etherx.jabber.org/streams"/>'
|
132
131
|
end
|
133
132
|
|
134
133
|
it 'ignores the client namespace on stanzas' do
|
135
|
-
|
134
|
+
process "<message type='chat' to='n@d' from='n@d/r' id='id1' xmlns='jabber:client'>",
|
136
135
|
"<body>exit</body>",
|
137
136
|
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>exit</body></html>",
|
138
137
|
"</message>"
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
138
|
+
client.data.size.should == 1
|
139
|
+
client.data[0].document.xpath('/message/body[.="exit"]').should_not be_empty
|
140
|
+
client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
143
141
|
end
|
144
142
|
|
145
143
|
it 'ignores the component namespace on stanzas' do
|
146
|
-
|
144
|
+
process "<message type='chat' to='n@d' from='n@d/r' id='id1' xmlns='jabber:component:accept'>",
|
147
145
|
"<body>exit</body>",
|
148
146
|
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>exit</body></html>",
|
149
147
|
"</message>"
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
@client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
148
|
+
client.data.size.should == 1
|
149
|
+
client.data[0].document.xpath('/message/body[.="exit"]').should_not be_empty
|
150
|
+
client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
154
151
|
end
|
155
152
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blather
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 1.5.5
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 1.5.5
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: niceogiri
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ! '>='
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 3.
|
69
|
+
version: 2.3.11
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 3.
|
77
|
+
version: 2.3.11
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: girl_friday
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -203,6 +203,22 @@ dependencies:
|
|
203
203
|
- - ! '>='
|
204
204
|
- !ruby/object:Gem::Version
|
205
205
|
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: countdownlatch
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ! '>='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
206
222
|
description: An XMPP DSL for Ruby written on top of EventMachine and Nokogiri
|
207
223
|
email: sprsquish@gmail.com
|
208
224
|
executables: []
|
@@ -295,6 +311,7 @@ files:
|
|
295
311
|
- lib/blather/stream/client.rb
|
296
312
|
- lib/blather/stream/component.rb
|
297
313
|
- lib/blather/stream/features.rb
|
314
|
+
- lib/blather/stream/features/register.rb
|
298
315
|
- lib/blather/stream/features/resource.rb
|
299
316
|
- lib/blather/stream/features/sasl.rb
|
300
317
|
- lib/blather/stream/features/session.rb
|
@@ -374,7 +391,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
374
391
|
version: '0'
|
375
392
|
segments:
|
376
393
|
- 0
|
377
|
-
hash:
|
394
|
+
hash: -4548531025459259087
|
378
395
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
379
396
|
none: false
|
380
397
|
requirements:
|
@@ -383,10 +400,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
383
400
|
version: '0'
|
384
401
|
segments:
|
385
402
|
- 0
|
386
|
-
hash:
|
403
|
+
hash: -4548531025459259087
|
387
404
|
requirements: []
|
388
405
|
rubyforge_project:
|
389
|
-
rubygems_version: 1.8.
|
406
|
+
rubygems_version: 1.8.24
|
390
407
|
signing_key:
|
391
408
|
specification_version: 3
|
392
409
|
summary: Simpler XMPP built for speed
|