blather 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|