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.
@@ -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
- [identities].flatten.each { |i| new_node.query << Identity.new(i) }
26
- [features].flatten.each { |f| new_node.query << Feature.new(f) }
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
- [items].flatten.each { |item| new_node.query << Item.new(item) }
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('command_ns:command', :command_ns => self.class.registered_ns)
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-"+id
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.read_attr :action, :to_sym
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.read_attr :status, :to_sym
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 (#{statusn}), use: #{VALID_STATUS*' '}"
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
- unless a
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
- a = []
204
- a << :execute
205
- actions.children.each do |action|
206
- a << action.name.to_sym
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 add_allowed_actions(allowed_actions)
215
- [allowed_actions].flatten.each do |action|
216
- if action && !VALID_ACTIONS.include?(action.to_sym)
217
- raise ArgumentError, "Invalid Action (#{action}), use: #{VALID_ACTIONS*' '}"
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(disallowed_actions)
227
- [disallowed_actions].flatten.each do |action|
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
- unless n
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.read_attr :type, :to_sym
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 "note"
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 "note", note_text
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
- X.new command.find_first('//ns:x', :ns => X.registered_ns)
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
@@ -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.add_fields([type[:fields]])
28
+ new_node.fields = type[:fields]
29
29
  else
30
30
  new_node.type = type
31
- new_node.add_fields([fields])
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 |f|
55
- Field.new f
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 add_fields(fields = [])
62
- [fields].flatten.each { |f| self << Field.new(f) }
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
- if i = self.find_first('ns:instructions', :ns => self.class.registered_ns)
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
- self << "<instructions>#{instructions}</instructions>"
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
- if t = self.find_first('ns:title', :ns => self.class.registered_ns)
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
- self << "<title>#{title}</title>"
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
- def self.new(type, var = nil, label = nil)
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 v = self.find_first('value')
207
- v.children.inner_text
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
- self << "<value>#{value}</value>"
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 d = self.find_first('desc')
224
- d.children.inner_text
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
- self << "<desc>#{description}</desc>"
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') ? true : false
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!(required = true)
247
- if self.find_first('required')
248
- if required==false
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('option').map do |f|
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 add_options(options = [])
270
- [options].flatten.each { |o| self << Option.new(o) }
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
- raise "Cannot compare #{self.class} with #{o.class}"
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 v = self.find_first('value')
324
- v.children.inner_text
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=(v)
362
+ def value=(value)
331
363
  self.remove_children :value
332
- self << "<value>#{v}</value>"
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
- # TODO: Deal with #reply/#reply! better?
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.wont_be_nil
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 an allowed_actions attribute' do
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.add_allowed_actions [:prev, :next]
134
- n.allowed_actions.must_equal [:execute, :prev, :next]
135
- n.remove_allowed_actions :prev
136
- n.allowed_actions.must_equal [:execute, :next]
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-name'
19
- type='{field-type}'
18
+ <field var='field-name4'
19
+ type='list-multi'
20
20
  label='description'>
21
21
  <desc/>
22
22
  <required/>
23
- <value>field-value</value>
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.add_fields [{:label => 'label', :type => 'text-single', :var => 'var'}]
131
+ di.fields = [{:label => 'label', :type => 'text-single', :var => 'var', :required => true}]
125
132
  di.fields.size.must_equal 1
126
- di.add_fields [Blather::Stanza::X::Field.new(*%w[text-single var1 label1])]
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! false
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.add_options [{:label => 'Person', :value => 'person'}]
200
+ di.options += [{:label => 'Person', :value => 'person'}]
194
201
  di.options.size.must_equal 1
195
- di.add_options [Blather::Stanza::X::Field::Option.new(*%w[person1 Person1])]
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 10
10
- version: 0.4.10
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-19 00:00:00 -07:00
18
+ date: 2010-07-29 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency