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