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.rb +35 -12
- data/lib/blather/client.rb +1 -1
- data/lib/blather/client/client.rb +19 -13
- data/lib/blather/client/dsl.rb +16 -0
- data/lib/blather/client/dsl/pubsub.rb +133 -0
- data/lib/blather/core_ext/active_support.rb +1 -117
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
- data/lib/blather/core_ext/nokogiri.rb +35 -0
- data/lib/blather/errors.rb +3 -20
- 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/jid.rb +1 -0
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +6 -1
- data/lib/blather/stanza.rb +35 -18
- data/lib/blather/stanza/disco.rb +7 -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/iq.rb +13 -8
- data/lib/blather/stanza/iq/query.rb +16 -8
- data/lib/blather/stanza/iq/roster.rb +33 -22
- data/lib/blather/stanza/message.rb +20 -31
- data/lib/blather/stanza/presence.rb +3 -5
- data/lib/blather/stanza/presence/status.rb +13 -21
- data/lib/blather/stanza/presence/subscription.rb +11 -16
- data/lib/blather/stanza/pubsub.rb +63 -0
- 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_owner.rb +41 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
- data/lib/blather/stream.rb +76 -168
- data/lib/blather/stream/client.rb +1 -2
- data/lib/blather/stream/component.rb +9 -5
- data/lib/blather/stream/features.rb +53 -0
- 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/parser.rb +70 -46
- data/lib/blather/xmpp_node.rb +113 -52
- 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 +54 -18
- 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
data/lib/blather/xmpp_node.rb
CHANGED
|
@@ -4,13 +4,13 @@ module Blather
|
|
|
4
4
|
# Base XML Node
|
|
5
5
|
# All XML classes subclass XMPPNode
|
|
6
6
|
# it allows the addition of helpers
|
|
7
|
-
class XMPPNode < XML::Node
|
|
7
|
+
class XMPPNode < Nokogiri::XML::Node
|
|
8
8
|
BASE_NAMES = %w[presence message iq].freeze
|
|
9
9
|
|
|
10
10
|
@@registrations = {}
|
|
11
11
|
|
|
12
|
-
class_inheritable_accessor :
|
|
13
|
-
:
|
|
12
|
+
class_inheritable_accessor :registered_ns,
|
|
13
|
+
:registered_name
|
|
14
14
|
|
|
15
15
|
##
|
|
16
16
|
# Lets a subclass register itself
|
|
@@ -19,9 +19,9 @@ module Blather
|
|
|
19
19
|
# up the class name of the object to instantiate when a new
|
|
20
20
|
# stanza is received
|
|
21
21
|
def self.register(name, ns = nil)
|
|
22
|
-
self.
|
|
23
|
-
self.
|
|
24
|
-
@@registrations[[self.
|
|
22
|
+
self.registered_name = name.to_s
|
|
23
|
+
self.registered_ns = ns
|
|
24
|
+
@@registrations[[self.registered_name, self.registered_ns]] = self
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
##
|
|
@@ -36,7 +36,7 @@ module Blather
|
|
|
36
36
|
# of that class and imports all the <tt>node</tt>'s attributes
|
|
37
37
|
# and children into it.
|
|
38
38
|
def self.import(node)
|
|
39
|
-
klass = class_from_registration(node.element_name, node.namespace)
|
|
39
|
+
klass = class_from_registration(node.element_name, (node.namespace.href if node.namespace))
|
|
40
40
|
if klass && klass != self
|
|
41
41
|
klass.import(node)
|
|
42
42
|
else
|
|
@@ -55,16 +55,18 @@ module Blather
|
|
|
55
55
|
# end
|
|
56
56
|
#
|
|
57
57
|
# n = Node.new
|
|
58
|
-
# n
|
|
58
|
+
# n[:type] = 'foo'
|
|
59
59
|
# n.type == :foo
|
|
60
|
-
# n
|
|
60
|
+
# n[:name] = 'bar'
|
|
61
61
|
# n.name == 'bar'
|
|
62
62
|
def self.attribute_reader(*syms)
|
|
63
63
|
opts = syms.last.is_a?(Hash) ? syms.pop : {}
|
|
64
|
+
convert_str = "val.#{opts[:call]} if val" if opts[:call]
|
|
64
65
|
syms.flatten.each do |sym|
|
|
65
66
|
class_eval(<<-END, __FILE__, __LINE__)
|
|
66
67
|
def #{sym}
|
|
67
|
-
|
|
68
|
+
val = self[:#{sym}]
|
|
69
|
+
#{convert_str}
|
|
68
70
|
end
|
|
69
71
|
END
|
|
70
72
|
end
|
|
@@ -79,13 +81,13 @@ module Blather
|
|
|
79
81
|
#
|
|
80
82
|
# n = Node.new
|
|
81
83
|
# n.type = 'foo'
|
|
82
|
-
# n
|
|
84
|
+
# n[:type] == 'foo'
|
|
83
85
|
def self.attribute_writer(*syms)
|
|
84
86
|
syms.flatten.each do |sym|
|
|
85
87
|
next if sym.is_a?(Hash)
|
|
86
88
|
class_eval(<<-END, __FILE__, __LINE__)
|
|
87
89
|
def #{sym}=(value)
|
|
88
|
-
|
|
90
|
+
self[:#{sym}] = value
|
|
89
91
|
end
|
|
90
92
|
END
|
|
91
93
|
end
|
|
@@ -110,14 +112,74 @@ module Blather
|
|
|
110
112
|
attribute_writer *syms
|
|
111
113
|
end
|
|
112
114
|
|
|
115
|
+
##
|
|
116
|
+
# Provides a content reader helper that returns the content of a node
|
|
117
|
+
# +method+ is the method to create
|
|
118
|
+
# +conversion+ is a method to call on the content before sending it back
|
|
119
|
+
# +node+ is the name of the content node (this defaults to the method name)
|
|
120
|
+
#
|
|
121
|
+
# class Node
|
|
122
|
+
# content_attr_reader :body
|
|
123
|
+
# content_attr_reader :type, :to_sym
|
|
124
|
+
# content_attr_reader :id, :to_i, :identity
|
|
125
|
+
# end
|
|
126
|
+
#
|
|
127
|
+
# n = Node.new 'foo'
|
|
128
|
+
# n.to_s == "<foo><body>foobarbaz</body><type>error</type><identity>1000</identity></foo>"
|
|
129
|
+
# n.body == 'foobarbaz'
|
|
130
|
+
# n.type == :error
|
|
131
|
+
# n.id == 1000
|
|
132
|
+
def self.content_attr_reader(method, conversion = nil, node = nil)
|
|
133
|
+
node ||= method
|
|
134
|
+
conversion = "val.#{conversion} if val.respond_to?(:#{conversion})" if conversion
|
|
135
|
+
class_eval(<<-END, __FILE__, __LINE__)
|
|
136
|
+
def #{method}
|
|
137
|
+
val = content_from :#{node}
|
|
138
|
+
#{conversion}
|
|
139
|
+
end
|
|
140
|
+
END
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
##
|
|
144
|
+
# Provides a content writer helper that creates or updates the content of a node
|
|
145
|
+
# +method+ is the method to create
|
|
146
|
+
# +node+ is the name of the node to create (defaults to the method name)
|
|
147
|
+
#
|
|
148
|
+
# class Node
|
|
149
|
+
# content_attr_writer :body
|
|
150
|
+
# content_attr_writer :id, :identity
|
|
151
|
+
# end
|
|
152
|
+
#
|
|
153
|
+
# n = Node.new 'foo'
|
|
154
|
+
# n.body = 'thebodytext'
|
|
155
|
+
# n.id = 'id-text'
|
|
156
|
+
# n.to_s == '<foo><body>thebodytext</body><identity>id-text</identity></foo>'
|
|
157
|
+
def self.content_attr_writer(method, node = nil)
|
|
158
|
+
node ||= method
|
|
159
|
+
class_eval(<<-END, __FILE__, __LINE__)
|
|
160
|
+
def #{method}=(val)
|
|
161
|
+
set_content_for :#{node}, val
|
|
162
|
+
end
|
|
163
|
+
END
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
##
|
|
167
|
+
# Provides a quick way of building +content_attr_reader+ and +content_attr_writer+
|
|
168
|
+
# for the same method and node
|
|
169
|
+
def self.content_attr_accessor(method, conversion = nil, node = nil)
|
|
170
|
+
content_attr_reader method, conversion, node
|
|
171
|
+
content_attr_writer method, node
|
|
172
|
+
end
|
|
173
|
+
|
|
113
174
|
##
|
|
114
175
|
# Automatically sets the namespace registered by the subclass
|
|
115
|
-
def
|
|
116
|
-
name ||= self.
|
|
117
|
-
content = content.to_s if content
|
|
176
|
+
def self.new(name = nil, doc = nil)
|
|
177
|
+
name ||= self.registered_name
|
|
118
178
|
|
|
119
|
-
super name.to_s,
|
|
120
|
-
|
|
179
|
+
node = super name.to_s, (doc || Nokogiri::XML::Document.new)
|
|
180
|
+
node.document.root = node unless doc
|
|
181
|
+
node.namespace = self.registered_ns unless BASE_NAMES.include?(name.to_s)
|
|
182
|
+
node
|
|
121
183
|
end
|
|
122
184
|
|
|
123
185
|
##
|
|
@@ -126,80 +188,79 @@ module Blather
|
|
|
126
188
|
self.class.import self
|
|
127
189
|
end
|
|
128
190
|
|
|
191
|
+
alias_method :nokogiri_namespace=, :namespace=
|
|
129
192
|
def namespace=(namespaces)
|
|
130
193
|
case namespaces
|
|
131
|
-
when XML::Namespace
|
|
132
|
-
self.
|
|
194
|
+
when Nokogiri::XML::Namespace
|
|
195
|
+
self.nokogiri_namespace = namespaces
|
|
133
196
|
when String
|
|
134
|
-
self.
|
|
197
|
+
self.add_namespace nil, namespaces
|
|
135
198
|
when Hash
|
|
199
|
+
if ns = namespaces.delete(nil)
|
|
200
|
+
self.add_namespace nil, ns
|
|
201
|
+
end
|
|
136
202
|
namespaces.each do |p, n|
|
|
137
|
-
|
|
203
|
+
ns = self.add_namespace p, n
|
|
204
|
+
self.nokogiri_namespace = ns
|
|
138
205
|
end
|
|
139
206
|
end
|
|
140
207
|
end
|
|
141
208
|
|
|
142
|
-
def
|
|
143
|
-
|
|
209
|
+
def namespace_href
|
|
210
|
+
namespace.href if namespace
|
|
144
211
|
end
|
|
145
212
|
|
|
146
213
|
##
|
|
147
214
|
# Remove a child with the name and (optionally) namespace given
|
|
148
215
|
def remove_child(name, ns = nil)
|
|
149
|
-
|
|
150
|
-
|
|
216
|
+
child = xpath(name, ns).first
|
|
217
|
+
child.remove if child
|
|
151
218
|
end
|
|
152
219
|
|
|
153
220
|
##
|
|
154
221
|
# Remove all children with a given name
|
|
155
222
|
def remove_children(name)
|
|
156
|
-
name
|
|
157
|
-
self.find(name).each { |n| n.remove! }
|
|
223
|
+
xpath("./*[local-name()='#{name}']").remove
|
|
158
224
|
end
|
|
159
225
|
|
|
160
226
|
##
|
|
161
227
|
# Pull the content from a child
|
|
162
|
-
def content_from(name)
|
|
163
|
-
|
|
164
|
-
|
|
228
|
+
def content_from(name, ns = nil)
|
|
229
|
+
child = xpath(name, ns).first
|
|
230
|
+
child.content if child
|
|
165
231
|
end
|
|
166
232
|
|
|
167
233
|
##
|
|
168
|
-
#
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
234
|
+
# Sets the content for the specified node.
|
|
235
|
+
# If the node exists it is updated. If not a new node is created
|
|
236
|
+
# If the node exists and the content is nil, the node will be removed entirely
|
|
237
|
+
def set_content_for(node, content = nil)
|
|
238
|
+
if content
|
|
239
|
+
child = xpath(node).first
|
|
240
|
+
self << (child = XMPPNode.new(node, self.document)) unless child
|
|
241
|
+
child.content = content
|
|
242
|
+
else
|
|
243
|
+
remove_child node
|
|
244
|
+
end
|
|
173
245
|
end
|
|
174
246
|
|
|
247
|
+
alias_method :copy, :dup
|
|
248
|
+
|
|
175
249
|
##
|
|
176
250
|
# Inherit all of <tt>stanza</tt>'s attributes and children
|
|
177
251
|
def inherit(stanza)
|
|
252
|
+
set_namespace stanza.namespace if stanza.namespace
|
|
178
253
|
inherit_attrs stanza.attributes
|
|
179
|
-
stanza.children.each { |c| self << c.
|
|
254
|
+
stanza.children.each { |c| self << c.dup }
|
|
180
255
|
self
|
|
181
256
|
end
|
|
182
257
|
|
|
183
258
|
##
|
|
184
259
|
# Inherit only <tt>stanza</tt>'s attributes
|
|
185
260
|
def inherit_attrs(attrs)
|
|
186
|
-
attrs.each { |
|
|
261
|
+
attrs.each { |name, value| self[name] = value }
|
|
187
262
|
self
|
|
188
263
|
end
|
|
189
|
-
|
|
190
|
-
##
|
|
191
|
-
# Turn itself into an XML string and remove all whitespace between nodes
|
|
192
|
-
def to_xml
|
|
193
|
-
# TODO: Fix this for HTML nodes (and any other that might require whitespace)
|
|
194
|
-
to_s.gsub(">\n<", '><')
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
##
|
|
198
|
-
# Override #find to work when a node isn't attached to a document
|
|
199
|
-
def find(what, nslist = nil)
|
|
200
|
-
what = what.to_s
|
|
201
|
-
(self.doc ? super(what, nslist) : select { |i| i.element_name == what })
|
|
202
|
-
end
|
|
203
264
|
end #XMPPNode
|
|
204
265
|
|
|
205
|
-
end
|
|
266
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
|
2
2
|
require 'blather/client/client'
|
|
3
3
|
|
|
4
|
-
describe
|
|
4
|
+
describe Blather::Client do
|
|
5
5
|
before do
|
|
6
6
|
@client = Blather::Client.new
|
|
7
7
|
end
|
|
@@ -13,13 +13,13 @@ describe 'Blather::Client' do
|
|
|
13
13
|
jid = 'me@me.com/test'
|
|
14
14
|
@client.must_respond_to :jid=
|
|
15
15
|
@client.jid = jid
|
|
16
|
-
@client.jid.must_be_kind_of JID
|
|
17
|
-
@client.jid.must_equal JID.new(jid)
|
|
16
|
+
@client.jid.must_be_kind_of Blather::JID
|
|
17
|
+
@client.jid.must_equal Blather::JID.new(jid)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'provides a reader for the roster' do
|
|
21
21
|
@client.must_respond_to :roster
|
|
22
|
-
@client.roster.must_be_kind_of Roster
|
|
22
|
+
@client.roster.must_be_kind_of Blather::Roster
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'provides a status reader' do
|
|
@@ -78,14 +78,8 @@ describe 'Blather::Client' do
|
|
|
78
78
|
@client.unbind
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
it 'raises an error if the stream type somehow is not supported' do
|
|
82
|
-
Blather::Stream::Component.stubs(:start).returns nil
|
|
83
|
-
@client.setup('me.com', 'secret').run
|
|
84
|
-
lambda { @client.post_init }.must_raise RuntimeError
|
|
85
|
-
end
|
|
86
|
-
|
|
87
81
|
it 'can register a temporary handler based on stanza ID' do
|
|
88
|
-
stanza = Stanza::Iq.new
|
|
82
|
+
stanza = Blather::Stanza::Iq.new
|
|
89
83
|
response = mock()
|
|
90
84
|
response.expects(:call)
|
|
91
85
|
@client.register_tmp_handler(stanza.id) { |_| response.call }
|
|
@@ -93,7 +87,7 @@ describe 'Blather::Client' do
|
|
|
93
87
|
end
|
|
94
88
|
|
|
95
89
|
it 'removes a tmp handler as soon as it is used' do
|
|
96
|
-
stanza = Stanza::Iq.new
|
|
90
|
+
stanza = Blather::Stanza::Iq.new
|
|
97
91
|
response = mock()
|
|
98
92
|
response.expects(:call)
|
|
99
93
|
@client.register_tmp_handler(stanza.id) { |_| response.call }
|
|
@@ -102,7 +96,7 @@ describe 'Blather::Client' do
|
|
|
102
96
|
end
|
|
103
97
|
|
|
104
98
|
it 'will create a handler then write the stanza' do
|
|
105
|
-
stanza = Stanza::Iq.new
|
|
99
|
+
stanza = Blather::Stanza::Iq.new
|
|
106
100
|
response = mock()
|
|
107
101
|
response.expects(:call)
|
|
108
102
|
@client.expects(:write).with do |s|
|
|
@@ -113,7 +107,7 @@ describe 'Blather::Client' do
|
|
|
113
107
|
end
|
|
114
108
|
|
|
115
109
|
it 'can register a handler' do
|
|
116
|
-
stanza = Stanza::Iq.new
|
|
110
|
+
stanza = Blather::Stanza::Iq.new
|
|
117
111
|
response = mock()
|
|
118
112
|
response.expects(:call).times(2)
|
|
119
113
|
@client.register_handler(:iq) { |_| response.call }
|
|
@@ -127,26 +121,8 @@ describe 'Blather::Client#write' do
|
|
|
127
121
|
@client = Blather::Client.new
|
|
128
122
|
end
|
|
129
123
|
|
|
130
|
-
it 'sets the from attr on a stanza' do
|
|
131
|
-
jid = 'me@me.com'
|
|
132
|
-
stanza = mock(:from => nil)
|
|
133
|
-
stanza.expects(:from=).with jid
|
|
134
|
-
@client.jid = jid
|
|
135
|
-
@client.write stanza
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
it 'does not set the from attr if it already exists' do
|
|
139
|
-
jid = 'me@me.com'
|
|
140
|
-
stanza = Stanza::Iq.new
|
|
141
|
-
stanza.from = jid
|
|
142
|
-
stanza.expects(:from).returns jid
|
|
143
|
-
stanza.expects(:from=).never
|
|
144
|
-
@client.jid = jid
|
|
145
|
-
@client.write stanza
|
|
146
|
-
end
|
|
147
|
-
|
|
148
124
|
it 'writes to the stream' do
|
|
149
|
-
stanza = Stanza::Iq.new
|
|
125
|
+
stanza = Blather::Stanza::Iq.new
|
|
150
126
|
stream = mock()
|
|
151
127
|
stream.expects(:send).with stanza
|
|
152
128
|
Blather::Stream::Client.expects(:start).returns stream
|
|
@@ -173,11 +149,11 @@ describe 'Blather::Client#status=' do
|
|
|
173
149
|
end
|
|
174
150
|
|
|
175
151
|
it 'writes the new status to the stream' do
|
|
176
|
-
Stanza::Presence::Status.stubs(:next_id).returns 0
|
|
152
|
+
Blather::Stanza::Presence::Status.stubs(:next_id).returns 0
|
|
177
153
|
status = [:away, 'message']
|
|
178
154
|
@client.expects(:write).with do |s|
|
|
179
|
-
s.must_be_kind_of Stanza::Presence::Status
|
|
180
|
-
s.to_s.must_equal Stanza::Presence::Status.new(*status).to_s
|
|
155
|
+
s.must_be_kind_of Blather::Stanza::Presence::Status
|
|
156
|
+
s.to_s.must_equal Blather::Stanza::Presence::Status.new(*status).to_s
|
|
181
157
|
end
|
|
182
158
|
@client.status = status
|
|
183
159
|
end
|
|
@@ -189,34 +165,34 @@ describe 'Blather::Client default handlers' do
|
|
|
189
165
|
end
|
|
190
166
|
|
|
191
167
|
it 're-raises errors' do
|
|
192
|
-
err = BlatherError.new
|
|
193
|
-
lambda { @client.receive_data err }.must_raise BlatherError
|
|
168
|
+
err = Blather::BlatherError.new
|
|
169
|
+
lambda { @client.receive_data err }.must_raise Blather::BlatherError
|
|
194
170
|
end
|
|
195
171
|
|
|
196
172
|
it 'responds to iq:get with a "service-unavailable" error' do
|
|
197
|
-
get = Stanza::Iq.new :get
|
|
198
|
-
err = StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
173
|
+
get = Blather::Stanza::Iq.new :get
|
|
174
|
+
err = Blather::StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
199
175
|
@client.expects(:write).with err
|
|
200
176
|
@client.receive_data get
|
|
201
177
|
end
|
|
202
178
|
|
|
203
179
|
it 'responds to iq:get with a "service-unavailable" error' do
|
|
204
|
-
get = Stanza::Iq.new :get
|
|
205
|
-
err = StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
206
|
-
@client.expects(:write).with err
|
|
180
|
+
get = Blather::Stanza::Iq.new :get
|
|
181
|
+
err = Blather::StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
182
|
+
@client.expects(:write).with { |n| n.to_s.must_equal err.to_s }
|
|
207
183
|
@client.receive_data get
|
|
208
184
|
end
|
|
209
185
|
|
|
210
186
|
it 'responds to iq:set with a "service-unavailable" error' do
|
|
211
|
-
get = Stanza::Iq.new :set
|
|
212
|
-
err = StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
213
|
-
@client.expects(:write).with err
|
|
187
|
+
get = Blather::Stanza::Iq.new :set
|
|
188
|
+
err = Blather::StanzaError.new(get, 'service-unavailable', :cancel).to_node
|
|
189
|
+
@client.expects(:write).with { |n| n.to_s.must_equal err.to_s }
|
|
214
190
|
@client.receive_data get
|
|
215
191
|
end
|
|
216
192
|
|
|
217
193
|
it 'handles status changes by updating the roster if the status is from a JID in the roster' do
|
|
218
194
|
jid = 'friend@jabber.local'
|
|
219
|
-
status = Stanza::Presence::Status.new :away
|
|
195
|
+
status = Blather::Stanza::Presence::Status.new :away
|
|
220
196
|
status.stubs(:from).returns jid
|
|
221
197
|
roster_item = mock()
|
|
222
198
|
roster_item.expects(:status=).with status
|
|
@@ -225,7 +201,7 @@ describe 'Blather::Client default handlers' do
|
|
|
225
201
|
end
|
|
226
202
|
|
|
227
203
|
it 'handles an incoming roster node by processing it through the roster' do
|
|
228
|
-
roster = Stanza::Iq::Roster.new
|
|
204
|
+
roster = Blather::Stanza::Iq::Roster.new
|
|
229
205
|
client_roster = mock()
|
|
230
206
|
client_roster.expects(:process).with roster
|
|
231
207
|
@client.stubs(:roster).returns client_roster
|
|
@@ -259,12 +235,12 @@ describe 'Blather::Client with a Client stream' do
|
|
|
259
235
|
end
|
|
260
236
|
|
|
261
237
|
it 'sends a request for the roster when post_init is called' do
|
|
262
|
-
@stream.expects(:send).with { |stanza| stanza.must_be_kind_of Stanza::Iq::Roster }
|
|
238
|
+
@stream.expects(:send).with { |stanza| stanza.must_be_kind_of Blather::Stanza::Iq::Roster }
|
|
263
239
|
@client.post_init
|
|
264
240
|
end
|
|
265
241
|
|
|
266
242
|
it 'calls the ready handler after post_init and roster is received' do
|
|
267
|
-
result_roster = Stanza::Iq::Roster.new :result
|
|
243
|
+
result_roster = Blather::Stanza::Iq::Roster.new :result
|
|
268
244
|
@stream.stubs(:send).with { |s| result_roster.id = s.id; @client.receive_data result_roster; true }
|
|
269
245
|
|
|
270
246
|
ready = mock()
|
|
@@ -277,7 +253,7 @@ end
|
|
|
277
253
|
describe 'Blather::Client guards' do
|
|
278
254
|
before do
|
|
279
255
|
@client = Blather::Client.new
|
|
280
|
-
@stanza = Stanza::Iq.new
|
|
256
|
+
@stanza = Blather::Stanza::Iq.new
|
|
281
257
|
@response = mock()
|
|
282
258
|
end
|
|
283
259
|
|
|
@@ -329,15 +305,15 @@ describe 'Blather::Client guards' do
|
|
|
329
305
|
@response.expects(:call).times(2)
|
|
330
306
|
@client.register_handler(:iq, :type => [:result, :error]) { |_| @response.call }
|
|
331
307
|
|
|
332
|
-
stanza = Stanza::Iq.new
|
|
308
|
+
stanza = Blather::Stanza::Iq.new
|
|
333
309
|
stanza.expects(:type).at_least_once.returns :result
|
|
334
310
|
@client.receive_data stanza
|
|
335
311
|
|
|
336
|
-
stanza = Stanza::Iq.new
|
|
312
|
+
stanza = Blather::Stanza::Iq.new
|
|
337
313
|
stanza.expects(:type).at_least_once.returns :error
|
|
338
314
|
@client.receive_data stanza
|
|
339
315
|
|
|
340
|
-
stanza = Stanza::Iq.new
|
|
316
|
+
stanza = Blather::Stanza::Iq.new
|
|
341
317
|
stanza.expects(:type).at_least_once.returns :get
|
|
342
318
|
@client.receive_data stanza
|
|
343
319
|
end
|
|
@@ -346,12 +322,12 @@ describe 'Blather::Client guards' do
|
|
|
346
322
|
@response.expects :call
|
|
347
323
|
@client.register_handler(:iq, :type => :get, :body => 'test') { |_| @response.call }
|
|
348
324
|
|
|
349
|
-
stanza = Stanza::Iq.new
|
|
325
|
+
stanza = Blather::Stanza::Iq.new
|
|
350
326
|
stanza.expects(:type).at_least_once.returns :get
|
|
351
327
|
stanza.expects(:body).returns 'test'
|
|
352
328
|
@client.receive_data stanza
|
|
353
329
|
|
|
354
|
-
stanza = Stanza::Iq.new
|
|
330
|
+
stanza = Blather::Stanza::Iq.new
|
|
355
331
|
stanza.expects(:type).at_least_once.returns :set
|
|
356
332
|
stanza.expects(:body).never
|
|
357
333
|
@client.receive_data stanza
|
|
@@ -361,12 +337,12 @@ describe 'Blather::Client guards' do
|
|
|
361
337
|
@response.expects(:call).times 2
|
|
362
338
|
@client.register_handler(:iq, [{:type => :get}, {:body => 'test'}]) { |_| @response.call }
|
|
363
339
|
|
|
364
|
-
stanza = Stanza::Iq.new
|
|
340
|
+
stanza = Blather::Stanza::Iq.new
|
|
365
341
|
stanza.expects(:type).at_least_once.returns :set
|
|
366
342
|
stanza.expects(:body).returns 'test'
|
|
367
343
|
@client.receive_data stanza
|
|
368
344
|
|
|
369
|
-
stanza = Stanza::Iq.new
|
|
345
|
+
stanza = Blather::Stanza::Iq.new
|
|
370
346
|
stanza.stubs(:type).at_least_once.returns :get
|
|
371
347
|
stanza.expects(:body).never
|
|
372
348
|
@client.receive_data stanza
|
|
@@ -383,6 +359,16 @@ describe 'Blather::Client guards' do
|
|
|
383
359
|
@client.receive_data @stanza
|
|
384
360
|
end
|
|
385
361
|
|
|
362
|
+
it 'can be an xpath and will send the result to the handler' do
|
|
363
|
+
@response.expects(:call).with do |stanza, xpath|
|
|
364
|
+
xpath.must_be_instance_of Nokogiri::XML::NodeSet
|
|
365
|
+
xpath.wont_be_empty
|
|
366
|
+
stanza.must_equal @stanza
|
|
367
|
+
end
|
|
368
|
+
@client.register_handler(:iq, "/iq[@id='#{@stanza.id}']") { |stanza, xpath| @response.call stanza, xpath }
|
|
369
|
+
@client.receive_data @stanza
|
|
370
|
+
end
|
|
371
|
+
|
|
386
372
|
it 'raises an error when a bad guard is tried' do
|
|
387
373
|
lambda { @client.register_handler(:iq, 0) {} }.must_raise RuntimeError
|
|
388
374
|
end
|