blather 0.4.10 → 0.4.11
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/lib/blather/stanza/disco/disco_info.rb +20 -2
- data/lib/blather/stanza/disco/disco_items.rb +10 -1
- data/lib/blather/stanza/iq/command.rb +61 -35
- data/lib/blather/stanza/x.rb +87 -51
- data/spec/blather/stanza/discos/disco_info_spec.rb +23 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +11 -0
- data/spec/blather/stanza/iq/command_spec.rb +50 -10
- data/spec/blather/stanza/x_spec.rb +17 -10
- metadata +4 -4
|
@@ -22,8 +22,8 @@ class Stanza
|
|
|
22
22
|
def self.new(type = nil, node = nil, identities = [], features = [])
|
|
23
23
|
new_node = super type
|
|
24
24
|
new_node.node = node
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
new_node.identities = [identities]
|
|
26
|
+
new_node.features = [features]
|
|
27
27
|
new_node
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -34,6 +34,15 @@ class Stanza
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# Add an array of identities
|
|
38
|
+
# @param identities the array of identities, passed directly to Identity.new
|
|
39
|
+
def identities=(identities)
|
|
40
|
+
query.find('//ns:identity', :ns => self.class.registered_ns).each &:remove
|
|
41
|
+
if identities
|
|
42
|
+
[identities].flatten.each { |i| self.query << Identity.new(i) }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
37
46
|
# List of feature objects
|
|
38
47
|
def features
|
|
39
48
|
query.find('//ns:feature', :ns => self.class.registered_ns).map do |f|
|
|
@@ -41,6 +50,15 @@ class Stanza
|
|
|
41
50
|
end
|
|
42
51
|
end
|
|
43
52
|
|
|
53
|
+
# Add an array of features
|
|
54
|
+
# @param features the array of features, passed directly to Feature.new
|
|
55
|
+
def features=(features)
|
|
56
|
+
query.find('//ns:feature', :ns => self.class.registered_ns).each &:remove
|
|
57
|
+
if features
|
|
58
|
+
[features].flatten.each { |f| self.query << Feature.new(f) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
44
62
|
class Identity < XMPPNode
|
|
45
63
|
# Create a new DiscoInfo Identity
|
|
46
64
|
# @overload new(node)
|
|
@@ -21,7 +21,7 @@ class Stanza
|
|
|
21
21
|
def self.new(type = nil, node = nil, items = [])
|
|
22
22
|
new_node = super type
|
|
23
23
|
new_node.node = node
|
|
24
|
-
|
|
24
|
+
new_node.items = [items]
|
|
25
25
|
new_node
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -34,6 +34,15 @@ class Stanza
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# Add an array of items
|
|
38
|
+
# @param items the array of items, passed directly to Item.new
|
|
39
|
+
def items=(items)
|
|
40
|
+
query.find('//ns:item', :ns => self.class.registered_ns).each &:remove
|
|
41
|
+
if items
|
|
42
|
+
[items].flatten.each { |i| self.query << Item.new(i) }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
37
46
|
# An individual Disco Item
|
|
38
47
|
class Item < XMPPNode
|
|
39
48
|
# Create a new Blather::Stanza::DiscoItems::Item
|
|
@@ -28,16 +28,27 @@ class Iq
|
|
|
28
28
|
new_node.command
|
|
29
29
|
new_node.node = node
|
|
30
30
|
new_node.action = action
|
|
31
|
-
new_node.new_sessionid!
|
|
32
31
|
new_node
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
# Overrides the parent method to ensure the current command node is destroyed
|
|
35
|
+
# and the action is set to execute if no action provided
|
|
36
36
|
#
|
|
37
37
|
# @see Blather::Stanza::Iq#inherit
|
|
38
38
|
def inherit(node)
|
|
39
39
|
command.remove
|
|
40
40
|
super
|
|
41
|
+
self.action = :execute unless self.action
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Overrides the parent method to ensure the reply has no action
|
|
46
|
+
#
|
|
47
|
+
# @return [self]
|
|
48
|
+
def reply!
|
|
49
|
+
super
|
|
50
|
+
self.action = nil
|
|
51
|
+
self
|
|
41
52
|
end
|
|
42
53
|
|
|
43
54
|
# Command node accessor
|
|
@@ -47,7 +58,7 @@ class Iq
|
|
|
47
58
|
# @return [Blather::XMPPNode]
|
|
48
59
|
def command
|
|
49
60
|
c = if self.class.registered_ns
|
|
50
|
-
find_first('
|
|
61
|
+
find_first('ns:command', :ns => self.class.registered_ns)
|
|
51
62
|
else
|
|
52
63
|
find_first('command')
|
|
53
64
|
end
|
|
@@ -80,6 +91,13 @@ class Iq
|
|
|
80
91
|
command[:sessionid]
|
|
81
92
|
end
|
|
82
93
|
|
|
94
|
+
# Check if there is a sessionid set
|
|
95
|
+
#
|
|
96
|
+
# @return [true, false]
|
|
97
|
+
def sessionid?
|
|
98
|
+
!sessionid.nil?
|
|
99
|
+
end
|
|
100
|
+
|
|
83
101
|
# Set the sessionid of the command
|
|
84
102
|
#
|
|
85
103
|
# @param [String, nil] sessionid the new sessionid
|
|
@@ -89,14 +107,14 @@ class Iq
|
|
|
89
107
|
|
|
90
108
|
# Generate a new session ID (SHA-1 hash)
|
|
91
109
|
def new_sessionid!
|
|
92
|
-
self.sessionid = "commandsession
|
|
110
|
+
self.sessionid = "commandsession-#{id}"
|
|
93
111
|
end
|
|
94
112
|
|
|
95
113
|
# Get the action of the command
|
|
96
114
|
#
|
|
97
115
|
# @return [Symbol, nil]
|
|
98
116
|
def action
|
|
99
|
-
command
|
|
117
|
+
(val = command[:action]) && val.to_sym
|
|
100
118
|
end
|
|
101
119
|
|
|
102
120
|
# Check if the command action is :cancel
|
|
@@ -148,7 +166,7 @@ class Iq
|
|
|
148
166
|
#
|
|
149
167
|
# @return [Symbol, nil]
|
|
150
168
|
def status
|
|
151
|
-
command
|
|
169
|
+
((val = command[:status]) && val.to_sym) || :executing
|
|
152
170
|
end
|
|
153
171
|
|
|
154
172
|
# Check if the command status is :executing
|
|
@@ -177,7 +195,7 @@ class Iq
|
|
|
177
195
|
# @param [:executing, :completed, :canceled] status the new status
|
|
178
196
|
def status=(status)
|
|
179
197
|
if status && !VALID_STATUS.include?(status.to_sym)
|
|
180
|
-
raise ArgumentError, "Invalid Action (#{
|
|
198
|
+
raise ArgumentError, "Invalid Action (#{status}), use: #{VALID_STATUS*' '}"
|
|
181
199
|
end
|
|
182
200
|
command[:status] = status
|
|
183
201
|
end
|
|
@@ -188,10 +206,9 @@ class Iq
|
|
|
188
206
|
#
|
|
189
207
|
# @return [Blather::XMPPNode]
|
|
190
208
|
def actions
|
|
191
|
-
a = find_first('actions')
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
(self << (a = XMPPNode.new('actions', self.document)))
|
|
209
|
+
unless a = self.command.find_first('ns:actions', :ns => self.class.registered_ns)
|
|
210
|
+
(self.command << (a = XMPPNode.new('actions', self.document)))
|
|
211
|
+
a.namespace = self.command.namespace
|
|
195
212
|
end
|
|
196
213
|
a
|
|
197
214
|
end
|
|
@@ -200,33 +217,37 @@ class Iq
|
|
|
200
217
|
#
|
|
201
218
|
# @return [[Symbol]]
|
|
202
219
|
def allowed_actions
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
([:execute] + actions.children.map { |action| action.name.to_sym }).uniq
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def primary_allowed_action
|
|
224
|
+
(actions[:execute] || :execute).to_sym
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def primary_allowed_action=(a)
|
|
228
|
+
if a && ![:prev, :next, :complete, :execute].include?(a.to_sym)
|
|
229
|
+
raise ArgumentError, "Invalid Action (#{a}), use: #{[:prev, :next, :complete, :execute]*' '}"
|
|
207
230
|
end
|
|
208
|
-
a
|
|
231
|
+
actions[:execute] = a
|
|
209
232
|
end
|
|
210
233
|
|
|
211
234
|
# Add allowed actions to the command
|
|
212
235
|
#
|
|
213
236
|
# @param [[:prev, :next, :complete]] allowed_actions the new allowed actions
|
|
214
|
-
def
|
|
215
|
-
[allowed_actions].flatten.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
end
|
|
219
|
-
actions << "<#{action.to_s}/>"
|
|
237
|
+
def allowed_actions=(allowed_actions)
|
|
238
|
+
allowed_actions = ([allowed_actions].flatten.map(&:to_sym) + [:execute]).uniq
|
|
239
|
+
if (invalid_actions = allowed_actions - VALID_ACTIONS).size > 0
|
|
240
|
+
raise ArgumentError, "Invalid Action(s) (#{invalid_actions*' '}), use: #{VALID_ACTIONS*' '}"
|
|
220
241
|
end
|
|
242
|
+
actions.children.map(&:remove)
|
|
243
|
+
allowed_actions.each { |action| actions << XMPPNode.new(action.to_s) }
|
|
221
244
|
end
|
|
222
245
|
|
|
223
246
|
# Remove allowed actions from the command
|
|
224
247
|
#
|
|
225
248
|
# @param [[:prev, :next, :complete]] disallowed_actions the allowed actions to remove
|
|
226
|
-
def remove_allowed_actions
|
|
227
|
-
|
|
228
|
-
actions.remove_children action.to_sym
|
|
229
|
-
end
|
|
249
|
+
def remove_allowed_actions!
|
|
250
|
+
actions.remove
|
|
230
251
|
end
|
|
231
252
|
|
|
232
253
|
# Command note accessor
|
|
@@ -235,10 +256,9 @@ class Iq
|
|
|
235
256
|
#
|
|
236
257
|
# @return [Blather::XMPPNode]
|
|
237
258
|
def note
|
|
238
|
-
n = find_first('note')
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
(self << (n = XMPPNode.new('note', self.document)))
|
|
259
|
+
unless n = self.command.find_first('ns:note', :ns => self.class.registered_ns)
|
|
260
|
+
(self.command << (n = XMPPNode.new('note', self.document)))
|
|
261
|
+
n.namespace = self.command.namespace
|
|
242
262
|
end
|
|
243
263
|
n
|
|
244
264
|
end
|
|
@@ -247,7 +267,7 @@ class Iq
|
|
|
247
267
|
#
|
|
248
268
|
# @return [Symbol, nil]
|
|
249
269
|
def note_type
|
|
250
|
-
note
|
|
270
|
+
(val = note[:type]) && val.to_sym
|
|
251
271
|
end
|
|
252
272
|
|
|
253
273
|
# Check if the command status is :info
|
|
@@ -283,23 +303,29 @@ class Iq
|
|
|
283
303
|
|
|
284
304
|
# Get the text of the command's note
|
|
285
305
|
def note_text
|
|
286
|
-
content_from
|
|
306
|
+
content_from :note
|
|
287
307
|
end
|
|
288
308
|
|
|
289
309
|
# Set the command's note text
|
|
290
310
|
#
|
|
291
311
|
# @param [String] note_text the command's new note text
|
|
292
312
|
def note_text=(note_text)
|
|
293
|
-
set_content_for
|
|
313
|
+
set_content_for :note, note_text
|
|
294
314
|
end
|
|
295
315
|
|
|
296
316
|
# Returns the command's x:data form child
|
|
297
317
|
def form
|
|
298
|
-
|
|
318
|
+
if found_x = command.find_first('ns:x', :ns => X.registered_ns)
|
|
319
|
+
x = X.new found_x
|
|
320
|
+
found_x.remove
|
|
321
|
+
else
|
|
322
|
+
x = X.new
|
|
323
|
+
end
|
|
324
|
+
self.command << x
|
|
325
|
+
x
|
|
299
326
|
end
|
|
300
|
-
|
|
301
327
|
end #Command
|
|
302
328
|
|
|
303
329
|
end #Iq
|
|
304
330
|
end #Stanza
|
|
305
|
-
end
|
|
331
|
+
end #Blather
|
data/lib/blather/stanza/x.rb
CHANGED
|
@@ -25,10 +25,10 @@ class Stanza
|
|
|
25
25
|
new_node.inherit type
|
|
26
26
|
when Hash
|
|
27
27
|
new_node.type = type[:type]
|
|
28
|
-
new_node.
|
|
28
|
+
new_node.fields = type[:fields]
|
|
29
29
|
else
|
|
30
30
|
new_node.type = type
|
|
31
|
-
new_node.
|
|
31
|
+
new_node.fields = fields
|
|
32
32
|
end
|
|
33
33
|
new_node
|
|
34
34
|
end
|
|
@@ -51,15 +51,25 @@ class Stanza
|
|
|
51
51
|
# List of field objects
|
|
52
52
|
# @return [Blather::Stanza::X::Field]
|
|
53
53
|
def fields
|
|
54
|
-
self.find('ns:field', :ns => self.class.registered_ns).map do |
|
|
55
|
-
Field.new
|
|
54
|
+
self.find('ns:field', :ns => self.class.registered_ns).map do |field|
|
|
55
|
+
Field.new(field)
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
# Find a field by var
|
|
60
|
+
# @param var the var for the field you wish to find
|
|
61
|
+
def field(var)
|
|
62
|
+
fields.detect { |f| f.var == var }
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
# Add an array of fields to form
|
|
60
66
|
# @param fields the array of fields, passed directly to Field.new
|
|
61
|
-
def
|
|
62
|
-
|
|
67
|
+
def fields=(fields)
|
|
68
|
+
remove_children :field
|
|
69
|
+
[fields].flatten.each do |field|
|
|
70
|
+
self << (f = Field.new(field))
|
|
71
|
+
f.namespace = self.namespace
|
|
72
|
+
end
|
|
63
73
|
end
|
|
64
74
|
|
|
65
75
|
# Check if the x is of type :cancel
|
|
@@ -94,9 +104,7 @@ class Stanza
|
|
|
94
104
|
#
|
|
95
105
|
# @return [String]
|
|
96
106
|
def instructions
|
|
97
|
-
|
|
98
|
-
i.children.inner_text
|
|
99
|
-
end
|
|
107
|
+
content_from 'ns:instructions', :ns => self.registered_ns
|
|
100
108
|
end
|
|
101
109
|
|
|
102
110
|
# Set the form's instructions
|
|
@@ -104,16 +112,18 @@ class Stanza
|
|
|
104
112
|
# @param [String] instructions the form's instructions
|
|
105
113
|
def instructions=(instructions)
|
|
106
114
|
self.remove_children :instructions
|
|
107
|
-
|
|
115
|
+
if instructions
|
|
116
|
+
self << (i = XMPPNode.new(:instructions, self.document))
|
|
117
|
+
i.namespace = self.namespace
|
|
118
|
+
i << instructions
|
|
119
|
+
end
|
|
108
120
|
end
|
|
109
121
|
|
|
110
122
|
# Retrieve the form's title
|
|
111
123
|
#
|
|
112
124
|
# @return [String]
|
|
113
125
|
def title
|
|
114
|
-
|
|
115
|
-
t.children.inner_text
|
|
116
|
-
end
|
|
126
|
+
content_from 'ns:title', :ns => self.registered_ns
|
|
117
127
|
end
|
|
118
128
|
|
|
119
129
|
# Set the form's title
|
|
@@ -121,7 +131,11 @@ class Stanza
|
|
|
121
131
|
# @param [String] title the form's title
|
|
122
132
|
def title=(title)
|
|
123
133
|
self.remove_children :title
|
|
124
|
-
|
|
134
|
+
if title
|
|
135
|
+
self << (t = XMPPNode.new(:title))
|
|
136
|
+
t.namespace = self.namespace
|
|
137
|
+
t << title
|
|
138
|
+
end
|
|
125
139
|
end
|
|
126
140
|
|
|
127
141
|
class Field < XMPPNode
|
|
@@ -137,12 +151,22 @@ class Stanza
|
|
|
137
151
|
# @option opts [:boolean, :fixed, :hidden, :"jid-multi", :"jid-single", :"list-multi", :"list-single", :"text-multi", :"text-private", :"text-single"] :type the type of the field
|
|
138
152
|
# @option opts [String] :var the variable for the field
|
|
139
153
|
# @option opts [String] :label the label for the field
|
|
154
|
+
# @option [String, nil] :value the value for the field
|
|
155
|
+
# @option [String, nil] :description the description for the field
|
|
156
|
+
# @option [true, false, nil] :required the required flag for the field
|
|
157
|
+
# @param [Array<Array, X::Field::Option>, nil] :options a list of field options.
|
|
158
|
+
# These are passed directly to X::Field::Option.new
|
|
140
159
|
# @overload new(type, var = nil, label = nil)
|
|
141
160
|
# Create a new Field by name
|
|
142
161
|
# @param [:boolean, :fixed, :hidden, :"jid-multi", :"jid-single", :"list-multi", :"list-single", :"text-multi", :"text-private", :"text-single"] type the type of the field
|
|
143
162
|
# @param [String, nil] var the variable for the field
|
|
144
163
|
# @param [String, nil] label the label for the field
|
|
145
|
-
|
|
164
|
+
# @param [String, nil] value the value for the field
|
|
165
|
+
# @param [String, nil] description the description for the field
|
|
166
|
+
# @param [true, false, nil] required the required flag for the field
|
|
167
|
+
# @param [Array<Array, X::Field::Option>, nil] options a list of field options.
|
|
168
|
+
# These are passed directly to X::Field::Option.new
|
|
169
|
+
def self.new(type, var = nil, label = nil, value = nil, description = nil, required = false, options = [])
|
|
146
170
|
new_node = super :field
|
|
147
171
|
|
|
148
172
|
case type
|
|
@@ -152,10 +176,18 @@ class Stanza
|
|
|
152
176
|
new_node.type = type[:type]
|
|
153
177
|
new_node.var = type[:var]
|
|
154
178
|
new_node.label = type[:label]
|
|
179
|
+
new_node.value = type[:value]
|
|
180
|
+
new_node.desc = type[:description]
|
|
181
|
+
new_node.required = type[:required]
|
|
182
|
+
new_node.options = type[:options]
|
|
155
183
|
else
|
|
156
184
|
new_node.type = type
|
|
157
185
|
new_node.var = var
|
|
158
186
|
new_node.label = label
|
|
187
|
+
new_node.value = value
|
|
188
|
+
new_node.desc = description
|
|
189
|
+
new_node.required = required
|
|
190
|
+
new_node.options = options
|
|
159
191
|
end
|
|
160
192
|
new_node
|
|
161
193
|
end
|
|
@@ -203,8 +235,10 @@ class Stanza
|
|
|
203
235
|
#
|
|
204
236
|
# @param [String]
|
|
205
237
|
def value
|
|
206
|
-
if
|
|
207
|
-
|
|
238
|
+
if self.namespace
|
|
239
|
+
content_from 'ns:value', :ns => self.namespace.href
|
|
240
|
+
else
|
|
241
|
+
content_from :value
|
|
208
242
|
end
|
|
209
243
|
end
|
|
210
244
|
|
|
@@ -213,15 +247,21 @@ class Stanza
|
|
|
213
247
|
# @param [String] value the field's value
|
|
214
248
|
def value=(value)
|
|
215
249
|
self.remove_children :value
|
|
216
|
-
|
|
250
|
+
if value
|
|
251
|
+
self << (v = XMPPNode.new(:value))
|
|
252
|
+
v.namespace = self.namespace
|
|
253
|
+
v << value
|
|
254
|
+
end
|
|
217
255
|
end
|
|
218
256
|
|
|
219
257
|
# Get the field's description
|
|
220
258
|
#
|
|
221
259
|
# @param [String]
|
|
222
260
|
def desc
|
|
223
|
-
if
|
|
224
|
-
|
|
261
|
+
if self.namespace
|
|
262
|
+
content_from 'ns:desc', :ns => self.namespace.href
|
|
263
|
+
else
|
|
264
|
+
content_from :desc
|
|
225
265
|
end
|
|
226
266
|
end
|
|
227
267
|
|
|
@@ -230,60 +270,50 @@ class Stanza
|
|
|
230
270
|
# @param [String] description the field's description
|
|
231
271
|
def desc=(description)
|
|
232
272
|
self.remove_children :desc
|
|
233
|
-
|
|
273
|
+
if description
|
|
274
|
+
self << (d = XMPPNode.new(:desc))
|
|
275
|
+
d.namespace = self.namespace
|
|
276
|
+
d << description
|
|
277
|
+
end
|
|
234
278
|
end
|
|
235
279
|
|
|
236
280
|
# Get the field's required flag
|
|
237
281
|
#
|
|
238
282
|
# @param [true, false]
|
|
239
283
|
def required?
|
|
240
|
-
self.find_first('required')
|
|
284
|
+
!self.find_first('required').nil?
|
|
241
285
|
end
|
|
242
286
|
|
|
243
287
|
# Set the field's required flag
|
|
244
288
|
#
|
|
245
289
|
# @param [true, false] required the field's required flag
|
|
246
|
-
def required
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
self.remove_children :required
|
|
250
|
-
end
|
|
251
|
-
else
|
|
252
|
-
if required==true
|
|
253
|
-
self << "<required/>"
|
|
254
|
-
end
|
|
255
|
-
end
|
|
290
|
+
def required=(required)
|
|
291
|
+
self.remove_children(:required) unless required
|
|
292
|
+
self << XMPPNode.new(:required) if required
|
|
256
293
|
end
|
|
257
294
|
|
|
258
295
|
# Extract list of option objects
|
|
259
296
|
#
|
|
260
297
|
# @return [Blather::Stanza::X::Field::Option]
|
|
261
298
|
def options
|
|
262
|
-
self.find(
|
|
263
|
-
Option.new f
|
|
264
|
-
end
|
|
299
|
+
self.find(:option).map { |f| Option.new(f) }
|
|
265
300
|
end
|
|
266
301
|
|
|
267
302
|
# Add an array of options to field
|
|
268
303
|
# @param options the array of options, passed directly to Option.new
|
|
269
|
-
def
|
|
270
|
-
|
|
304
|
+
def options=(options)
|
|
305
|
+
remove_children :option
|
|
306
|
+
if options
|
|
307
|
+
[options].flatten.each { |o| self << Option.new(o) }
|
|
308
|
+
end
|
|
271
309
|
end
|
|
272
310
|
|
|
273
311
|
# Compare two Field objects by type, var and label
|
|
274
312
|
# @param [X::Field] o the Field object to compare against
|
|
275
313
|
# @return [true, false]
|
|
276
314
|
def eql?(o)
|
|
277
|
-
unless o.is_a?(self.class)
|
|
278
|
-
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
o.type == self.type &&
|
|
282
|
-
o.var == self.var &&
|
|
283
|
-
o.label == self.label &&
|
|
284
|
-
o.desc == self.desc &&
|
|
285
|
-
o.required? == self.required? &&
|
|
286
|
-
o.value == self.value
|
|
315
|
+
raise "Cannot compare #{self.class} with #{o.class}" unless o.is_a?(self.class)
|
|
316
|
+
![:type, :var, :label, :desc, :required?, :value].detect { |m| o.send(m) != self.send(m) }
|
|
287
317
|
end
|
|
288
318
|
alias_method :==, :eql?
|
|
289
319
|
|
|
@@ -320,16 +350,22 @@ class Stanza
|
|
|
320
350
|
# The Field Option's value
|
|
321
351
|
# @return [String]
|
|
322
352
|
def value
|
|
323
|
-
if
|
|
324
|
-
|
|
353
|
+
if self.namespace
|
|
354
|
+
content_from 'ns:value', :ns => self.namespace.href
|
|
355
|
+
else
|
|
356
|
+
content_from :value
|
|
325
357
|
end
|
|
326
358
|
end
|
|
327
359
|
|
|
328
360
|
# Set the Field Option's value
|
|
329
361
|
# @param [String] value the new value for the field option
|
|
330
|
-
def value=(
|
|
362
|
+
def value=(value)
|
|
331
363
|
self.remove_children :value
|
|
332
|
-
|
|
364
|
+
if value
|
|
365
|
+
self << (v = XMPPNode.new(:value))
|
|
366
|
+
v.namespace = self.namespace
|
|
367
|
+
v << value
|
|
368
|
+
end
|
|
333
369
|
end
|
|
334
370
|
|
|
335
371
|
# The Field Option's label
|
|
@@ -54,6 +54,29 @@ describe Blather::Stanza::Iq::DiscoInfo do
|
|
|
54
54
|
n.to = 'to@jid.com'
|
|
55
55
|
n.find("/iq[@to='to@jid.com' and @type='get' and @id='#{n.id}']/ns:query[@node='/path/to/node']", :ns => Blather::Stanza::Iq::DiscoInfo.registered_ns).wont_be_empty
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
it 'allows adding of identities' do
|
|
59
|
+
di = Blather::Stanza::Iq::DiscoInfo.new
|
|
60
|
+
di.identities.size.must_equal 0
|
|
61
|
+
di.identities = [{:name => 'name', :type => 'type', :category => 'category'}]
|
|
62
|
+
di.identities.size.must_equal 1
|
|
63
|
+
di.identities += [Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category])]
|
|
64
|
+
di.identities.size.must_equal 2
|
|
65
|
+
di.identities = nil
|
|
66
|
+
di.identities.size.must_equal 0
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'allows adding of features' do
|
|
70
|
+
di = Blather::Stanza::Iq::DiscoInfo.new
|
|
71
|
+
di.features.size.must_equal 0
|
|
72
|
+
di.features = ["feature1"]
|
|
73
|
+
di.features.size.must_equal 1
|
|
74
|
+
di.features += [Blather::Stanza::Iq::DiscoInfo::Feature.new "feature2"]
|
|
75
|
+
di.features.size.must_equal 2
|
|
76
|
+
di.features = nil
|
|
77
|
+
di.features.size.must_equal 0
|
|
78
|
+
end
|
|
79
|
+
|
|
57
80
|
end
|
|
58
81
|
|
|
59
82
|
describe 'Blather::Stanza::Iq::DiscoInfo identities' do
|
|
@@ -102,6 +102,17 @@ describe Blather::Stanza::Iq::DiscoItems do
|
|
|
102
102
|
di.items.size.must_equal 2
|
|
103
103
|
di.items.each { |i| control.include?(i).must_equal true }
|
|
104
104
|
end
|
|
105
|
+
|
|
106
|
+
it 'allows adding of items' do
|
|
107
|
+
di = Blather::Stanza::Iq::DiscoItems.new
|
|
108
|
+
di.items.size.must_equal 0
|
|
109
|
+
di.items = [{:jid => 'foo@bar/baz', :node => 'node', :name => 'name'}]
|
|
110
|
+
di.items.size.must_equal 1
|
|
111
|
+
di.items += [Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name])]
|
|
112
|
+
di.items.size.must_equal 2
|
|
113
|
+
di.items = nil
|
|
114
|
+
di.items.size.must_equal 0
|
|
115
|
+
end
|
|
105
116
|
end
|
|
106
117
|
|
|
107
118
|
describe Blather::Stanza::Iq::DiscoItems::Item do
|
|
@@ -8,7 +8,6 @@ def command_xml
|
|
|
8
8
|
id='form2'>
|
|
9
9
|
<command xmlns='http://jabber.org/protocol/commands'
|
|
10
10
|
node='node1'
|
|
11
|
-
action='execute'
|
|
12
11
|
sessionid='dqjiodmqlmakm'>
|
|
13
12
|
<x xmlns='jabber:x:data' type='form'>
|
|
14
13
|
<field var='field-name' type='text-single' label='description' />
|
|
@@ -86,7 +85,18 @@ describe Blather::Stanza::Iq::Command do
|
|
|
86
85
|
c.type.must_equal :result
|
|
87
86
|
end
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
it 'removes action on reply' do
|
|
89
|
+
c = Blather::XMPPNode.import parse_stanza(command_xml).root
|
|
90
|
+
c.action.must_equal :execute
|
|
91
|
+
c.reply.action.must_equal nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'removes action on reply!' do
|
|
95
|
+
c = Blather::XMPPNode.import parse_stanza(command_xml).root
|
|
96
|
+
c.action.must_equal :execute
|
|
97
|
+
c.reply!
|
|
98
|
+
c.action.must_equal nil
|
|
99
|
+
end
|
|
90
100
|
|
|
91
101
|
it 'can be registered under a namespace' do
|
|
92
102
|
class CommandNs < Blather::Stanza::Iq::Command; register :command_ns, nil, 'command:ns'; end
|
|
@@ -113,27 +123,53 @@ describe Blather::Stanza::Iq::Command do
|
|
|
113
123
|
n.action.must_equal :cancel
|
|
114
124
|
end
|
|
115
125
|
|
|
126
|
+
it 'must default action to :execute on import' do
|
|
127
|
+
n = Blather::XMPPNode.import(parse_stanza(command_xml).root)
|
|
128
|
+
n.action.must_equal :execute
|
|
129
|
+
end
|
|
130
|
+
|
|
116
131
|
it 'has a status attribute' do
|
|
117
132
|
n = Blather::Stanza::Iq::Command.new
|
|
118
|
-
n.status.must_equal nil
|
|
119
|
-
n.status = :executing
|
|
120
133
|
n.status.must_equal :executing
|
|
134
|
+
n.status = :completed
|
|
135
|
+
n.status.must_equal :completed
|
|
121
136
|
end
|
|
122
137
|
|
|
123
138
|
it 'has a sessionid attribute' do
|
|
124
139
|
n = Blather::Stanza::Iq::Command.new
|
|
125
|
-
n.sessionid.
|
|
140
|
+
n.sessionid.must_equal nil
|
|
126
141
|
n.sessionid = "somerandomstring"
|
|
127
142
|
n.sessionid.must_equal Digest::SHA1.hexdigest("somerandomstring")
|
|
128
143
|
end
|
|
129
144
|
|
|
130
|
-
it 'has
|
|
145
|
+
it 'has a sessionid? attribute' do
|
|
131
146
|
n = Blather::Stanza::Iq::Command.new
|
|
147
|
+
n.sessionid?.must_equal false
|
|
148
|
+
n.new_sessionid!
|
|
149
|
+
n.sessionid?.must_equal true
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'has an allowed_actions attribute' do
|
|
153
|
+
n = Blather::XMPPNode.import parse_stanza(command_xml).root
|
|
154
|
+
n.allowed_actions.must_equal [:execute]
|
|
155
|
+
n.allowed_actions = [:next, :prev]
|
|
156
|
+
(n.allowed_actions - [:next, :prev, :execute]).must_be_empty
|
|
157
|
+
n.remove_allowed_actions!
|
|
132
158
|
n.allowed_actions.must_equal [:execute]
|
|
133
|
-
n.
|
|
134
|
-
n.allowed_actions
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
n.allowed_actions += [:next]
|
|
160
|
+
(n.allowed_actions - [:next, :execute]).must_be_empty
|
|
161
|
+
|
|
162
|
+
r = Blather::Stanza::Iq::Command.new
|
|
163
|
+
r.allowed_actions.must_equal [:execute]
|
|
164
|
+
r.allowed_actions += [:prev]
|
|
165
|
+
(r.allowed_actions - [:prev, :execute]).must_be_empty
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it 'has a primary_allowed_action attribute' do
|
|
169
|
+
n = Blather::XMPPNode.import parse_stanza(command_xml).root
|
|
170
|
+
n.primary_allowed_action.must_equal :execute
|
|
171
|
+
n.primary_allowed_action = :next
|
|
172
|
+
n.primary_allowed_action.must_equal :next
|
|
137
173
|
end
|
|
138
174
|
|
|
139
175
|
it 'has a note_type attribute' do
|
|
@@ -155,5 +191,9 @@ describe Blather::Stanza::Iq::Command do
|
|
|
155
191
|
n.form.fields.size.must_equal 1
|
|
156
192
|
n.form.fields.map { |f| f.class }.uniq.must_equal [Blather::Stanza::X::Field]
|
|
157
193
|
n.form.must_be_instance_of Blather::Stanza::X
|
|
194
|
+
|
|
195
|
+
r = Blather::Stanza::Iq::Command.new
|
|
196
|
+
r.form.type = :form
|
|
197
|
+
r.form.type.must_equal :form
|
|
158
198
|
end
|
|
159
199
|
end
|
|
@@ -15,12 +15,12 @@ def x_xml
|
|
|
15
15
|
<field var='field-name3'
|
|
16
16
|
type='text-single'
|
|
17
17
|
label='description' />
|
|
18
|
-
<field var='field-
|
|
19
|
-
type='
|
|
18
|
+
<field var='field-name4'
|
|
19
|
+
type='list-multi'
|
|
20
20
|
label='description'>
|
|
21
21
|
<desc/>
|
|
22
22
|
<required/>
|
|
23
|
-
<value>field-
|
|
23
|
+
<value>field-value4</value>
|
|
24
24
|
<option label='option-label'><value>option-value</value></option>
|
|
25
25
|
<option label='option-label'><value>option-value</value></option>
|
|
26
26
|
</field>
|
|
@@ -81,6 +81,13 @@ describe Blather::Stanza::X do
|
|
|
81
81
|
r.fields.map { |f| f.class }.uniq.must_equal [Blather::Stanza::X::Field]
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
it 'returns a field object for a particular var' do
|
|
85
|
+
x = Blather::Stanza::X.new parse_stanza(x_xml).root
|
|
86
|
+
f = x.field 'field-name4'
|
|
87
|
+
f.must_be_instance_of Blather::Stanza::X::Field
|
|
88
|
+
f.value.must_equal 'field-value4'
|
|
89
|
+
end
|
|
90
|
+
|
|
84
91
|
it 'takes a list of hashes for fields' do
|
|
85
92
|
fields = [
|
|
86
93
|
{:label => 'label', :type => 'text-single', :var => 'var'},
|
|
@@ -121,9 +128,9 @@ describe Blather::Stanza::X do
|
|
|
121
128
|
it 'allows adding of fields' do
|
|
122
129
|
di = Blather::Stanza::X.new nil
|
|
123
130
|
di.fields.size.must_equal 0
|
|
124
|
-
di.
|
|
131
|
+
di.fields = [{:label => 'label', :type => 'text-single', :var => 'var', :required => true}]
|
|
125
132
|
di.fields.size.must_equal 1
|
|
126
|
-
di.
|
|
133
|
+
di.fields += [Blather::Stanza::X::Field.new(*%w[text-single var1 label1])]
|
|
127
134
|
di.fields.size.must_equal 2
|
|
128
135
|
end
|
|
129
136
|
|
|
@@ -171,9 +178,9 @@ describe Blather::Stanza::X::Field do
|
|
|
171
178
|
it 'has a required? attribute' do
|
|
172
179
|
n = Blather::Stanza::X::Field.new 'text-single', 'subject', 'Music from the time of Shakespeare'
|
|
173
180
|
n.required?.must_equal false
|
|
174
|
-
n.required
|
|
181
|
+
n.required = true
|
|
175
182
|
n.required?.must_equal true
|
|
176
|
-
n.required
|
|
183
|
+
n.required = false
|
|
177
184
|
n.required?.must_equal false
|
|
178
185
|
end
|
|
179
186
|
|
|
@@ -190,9 +197,9 @@ describe Blather::Stanza::X::Field do
|
|
|
190
197
|
it 'allows adding of options' do
|
|
191
198
|
di = Blather::Stanza::X::Field.new nil
|
|
192
199
|
di.options.size.must_equal 0
|
|
193
|
-
di.
|
|
200
|
+
di.options += [{:label => 'Person', :value => 'person'}]
|
|
194
201
|
di.options.size.must_equal 1
|
|
195
|
-
di.
|
|
202
|
+
di.options += [Blather::Stanza::X::Field::Option.new(*%w[person1 Person1])]
|
|
196
203
|
di.options.size.must_equal 2
|
|
197
204
|
end
|
|
198
205
|
|
|
@@ -225,4 +232,4 @@ describe Blather::Stanza::X::Field::Option do
|
|
|
225
232
|
n.label = 'Book 2'
|
|
226
233
|
n.label.must_equal 'Book 2'
|
|
227
234
|
end
|
|
228
|
-
end
|
|
235
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: blather
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 25
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 4
|
|
9
|
-
-
|
|
10
|
-
version: 0.4.
|
|
9
|
+
- 11
|
|
10
|
+
version: 0.4.11
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Jeff Smick
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2010-07-
|
|
18
|
+
date: 2010-07-29 00:00:00 -07:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|