shingara-blather 0.4.8
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 +22 -0
- data/README.md +162 -0
- data/examples/echo.rb +18 -0
- data/examples/execute.rb +16 -0
- data/examples/ping_pong.rb +37 -0
- data/examples/print_hierarchy.rb +76 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/stream_only.rb +27 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +310 -0
- data/lib/blather/client/dsl/pubsub.rb +170 -0
- data/lib/blather/client/dsl.rb +264 -0
- data/lib/blather/client.rb +87 -0
- data/lib/blather/core_ext/nokogiri.rb +40 -0
- data/lib/blather/errors/sasl_error.rb +43 -0
- data/lib/blather/errors/stanza_error.rb +107 -0
- data/lib/blather/errors/stream_error.rb +82 -0
- data/lib/blather/errors.rb +69 -0
- data/lib/blather/jid.rb +142 -0
- data/lib/blather/roster.rb +111 -0
- data/lib/blather/roster_item.rb +122 -0
- data/lib/blather/stanza/disco/disco_info.rb +176 -0
- data/lib/blather/stanza/disco/disco_items.rb +132 -0
- data/lib/blather/stanza/disco.rb +25 -0
- data/lib/blather/stanza/iq/query.rb +53 -0
- data/lib/blather/stanza/iq/roster.rb +179 -0
- data/lib/blather/stanza/iq.rb +138 -0
- data/lib/blather/stanza/message.rb +332 -0
- data/lib/blather/stanza/presence/status.rb +212 -0
- data/lib/blather/stanza/presence/subscription.rb +101 -0
- data/lib/blather/stanza/presence.rb +163 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
- data/lib/blather/stanza/pubsub/create.rb +65 -0
- data/lib/blather/stanza/pubsub/errors.rb +18 -0
- data/lib/blather/stanza/pubsub/event.rb +123 -0
- data/lib/blather/stanza/pubsub/items.rb +103 -0
- data/lib/blather/stanza/pubsub/publish.rb +103 -0
- data/lib/blather/stanza/pubsub/retract.rb +92 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
- data/lib/blather/stanza/pubsub/subscription.rb +134 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +81 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +68 -0
- data/lib/blather/stanza/pubsub.rb +129 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
- data/lib/blather/stanza/pubsub_owner.rb +51 -0
- data/lib/blather/stanza.rb +149 -0
- data/lib/blather/stream/client.rb +31 -0
- data/lib/blather/stream/component.rb +38 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/features/sasl.rb +187 -0
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +102 -0
- data/lib/blather/stream.rb +231 -0
- data/lib/blather/xmpp_node.rb +218 -0
- data/lib/blather.rb +78 -0
- data/spec/blather/client/client_spec.rb +559 -0
- data/spec/blather/client/dsl/pubsub_spec.rb +462 -0
- data/spec/blather/client/dsl_spec.rb +143 -0
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +33 -0
- data/spec/blather/errors/stanza_error_spec.rb +129 -0
- data/spec/blather/errors/stream_error_spec.rb +108 -0
- data/spec/blather/errors_spec.rb +33 -0
- data/spec/blather/jid_spec.rb +87 -0
- data/spec/blather/roster_item_spec.rb +96 -0
- data/spec/blather/roster_spec.rb +103 -0
- data/spec/blather/stanza/discos/disco_info_spec.rb +226 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +148 -0
- data/spec/blather/stanza/iq/query_spec.rb +64 -0
- data/spec/blather/stanza/iq/roster_spec.rb +140 -0
- data/spec/blather/stanza/iq_spec.rb +45 -0
- data/spec/blather/stanza/message_spec.rb +132 -0
- data/spec/blather/stanza/presence/status_spec.rb +132 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +105 -0
- data/spec/blather/stanza/presence_spec.rb +66 -0
- 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 +67 -0
- data/spec/blather/stanza_spec.rb +116 -0
- data/spec/blather/stream/client_spec.rb +1011 -0
- data/spec/blather/stream/component_spec.rb +95 -0
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +231 -0
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +43 -0
- metadata +249 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
def disco_info_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<iq type='result'
|
|
6
|
+
from='romeo@montague.net/orchard'
|
|
7
|
+
to='juliet@capulet.com/balcony'
|
|
8
|
+
id='info4'>
|
|
9
|
+
<query xmlns='http://jabber.org/protocol/disco#info'>
|
|
10
|
+
<identity
|
|
11
|
+
category='client'
|
|
12
|
+
type='pc'
|
|
13
|
+
name='Gabber'/>
|
|
14
|
+
<feature var='jabber:iq:time'/>
|
|
15
|
+
<feature var='jabber:iq:version'/>
|
|
16
|
+
</query>
|
|
17
|
+
</iq>
|
|
18
|
+
XML
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe Blather::Stanza::Iq::DiscoInfo do
|
|
22
|
+
it 'registers itself' do
|
|
23
|
+
Blather::XMPPNode.class_from_registration(:query, 'http://jabber.org/protocol/disco#info').must_equal Blather::Stanza::Iq::DiscoInfo
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'must be importable' do
|
|
27
|
+
doc = parse_stanza disco_info_xml
|
|
28
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Iq::DiscoInfo
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'has a node attribute' do
|
|
32
|
+
n = Blather::Stanza::Iq::DiscoInfo.new nil, 'music', [], []
|
|
33
|
+
n.node.must_equal 'music'
|
|
34
|
+
n.node = :foo
|
|
35
|
+
n.node.must_equal 'foo'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'inherits a list of identities' do
|
|
39
|
+
n = parse_stanza disco_info_xml
|
|
40
|
+
r = Blather::Stanza::Iq::DiscoInfo.new.inherit n.root
|
|
41
|
+
r.identities.size.must_equal 1
|
|
42
|
+
r.identities.map { |i| i.class }.uniq.must_equal [Blather::Stanza::Iq::DiscoInfo::Identity]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'inherits a list of features' do
|
|
46
|
+
n = parse_stanza disco_info_xml
|
|
47
|
+
r = Blather::Stanza::Iq::DiscoInfo.new.inherit n.root
|
|
48
|
+
r.features.size.must_equal 2
|
|
49
|
+
r.features.map { |i| i.class }.uniq.must_equal [Blather::Stanza::Iq::DiscoInfo::Feature]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'is constructed properly' do
|
|
53
|
+
n = Blather::Stanza::Iq::DiscoInfo.new :get, '/path/to/node'
|
|
54
|
+
n.to = 'to@jid.com'
|
|
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
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe 'Blather::Stanza::Iq::DiscoInfo identities' do
|
|
60
|
+
it 'takes a list of hashes for identities' do
|
|
61
|
+
ids = [
|
|
62
|
+
{:name => 'name', :type => 'type', :category => 'category'},
|
|
63
|
+
{:name => 'name1', :type => 'type1', :category => 'category1'},
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
control = [ Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
|
67
|
+
Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
|
68
|
+
|
|
69
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, ids
|
|
70
|
+
di.identities.size.must_equal 2
|
|
71
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'takes a list of Identity objects as identities' do
|
|
75
|
+
control = [ Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
|
76
|
+
Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
|
77
|
+
|
|
78
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, control
|
|
79
|
+
di.identities.size.must_equal 2
|
|
80
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'takes a single hash as identity' do
|
|
84
|
+
control = [Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category])]
|
|
85
|
+
|
|
86
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, {:name => 'name', :type => 'type', :category => 'category'}
|
|
87
|
+
di.identities.size.must_equal 1
|
|
88
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'takes a single identity object as identity' do
|
|
92
|
+
control = [Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category])]
|
|
93
|
+
|
|
94
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, control.first
|
|
95
|
+
di.identities.size.must_equal 1
|
|
96
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'takes a mix of hashes and identity objects as identities' do
|
|
100
|
+
ids = [
|
|
101
|
+
{:name => 'name', :type => 'type', :category => 'category'},
|
|
102
|
+
Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1]),
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
control = [ Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
|
106
|
+
Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
|
107
|
+
|
|
108
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, ids
|
|
109
|
+
di.identities.size.must_equal 2
|
|
110
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe 'Blather::Stanza::Iq::DiscoInfo features' do
|
|
115
|
+
it 'takes a list of features as strings' do
|
|
116
|
+
features = %w[feature1 feature2 feature3]
|
|
117
|
+
control = features.map { |f| Blather::Stanza::Iq::DiscoInfo::Feature.new f }
|
|
118
|
+
|
|
119
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, [], features
|
|
120
|
+
di.features.size.must_equal 3
|
|
121
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'takes a list of features as Feature objects' do
|
|
125
|
+
features = %w[feature1 feature2 feature3]
|
|
126
|
+
control = features.map { |f| Blather::Stanza::Iq::DiscoInfo::Feature.new f }
|
|
127
|
+
|
|
128
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, [], control
|
|
129
|
+
di.features.size.must_equal 3
|
|
130
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'takes a single string' do
|
|
134
|
+
control = [Blather::Stanza::Iq::DiscoInfo::Feature.new('feature1')]
|
|
135
|
+
|
|
136
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, [], 'feature1'
|
|
137
|
+
di.features.size.must_equal 1
|
|
138
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'takes a single Feature object' do
|
|
142
|
+
control = [Blather::Stanza::Iq::DiscoInfo::Feature.new('feature1')]
|
|
143
|
+
|
|
144
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, [], control.first
|
|
145
|
+
di.features.size.must_equal 1
|
|
146
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'takes a mixed list of features as Feature objects and strings' do
|
|
150
|
+
features = %w[feature1 feature2 feature3]
|
|
151
|
+
control = features.map { |f| Blather::Stanza::Iq::DiscoInfo::Feature.new f }
|
|
152
|
+
features[1] = control[1]
|
|
153
|
+
|
|
154
|
+
di = Blather::Stanza::Iq::DiscoInfo.new nil, nil, [], features
|
|
155
|
+
di.features.size.must_equal 3
|
|
156
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
describe Blather::Stanza::Iq::DiscoInfo::Identity do
|
|
161
|
+
it 'will auto-inherit nodes' do
|
|
162
|
+
n = parse_stanza "<identity name='Personal Events' type='pep' category='pubsub' node='publish' />"
|
|
163
|
+
i = Blather::Stanza::Iq::DiscoInfo::Identity.new n.root
|
|
164
|
+
i.name.must_equal 'Personal Events'
|
|
165
|
+
i.type.must_equal :pep
|
|
166
|
+
i.category.must_equal :pubsub
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it 'has a category attribute' do
|
|
170
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
171
|
+
n.category.must_equal :cat
|
|
172
|
+
n.category = :foo
|
|
173
|
+
n.category.must_equal :foo
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it 'has a type attribute' do
|
|
177
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
178
|
+
n.type.must_equal :type
|
|
179
|
+
n.type = :foo
|
|
180
|
+
n.type.must_equal :foo
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'has a name attribute' do
|
|
184
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
185
|
+
n.name.must_equal 'name'
|
|
186
|
+
n.name = :foo
|
|
187
|
+
n.name.must_equal 'foo'
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'raises an error if equality is sent a non DiscoInfo::Identity object' do
|
|
191
|
+
a = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
192
|
+
lambda { a == 'foo' }.must_raise RuntimeError
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it 'can determine equality' do
|
|
196
|
+
a = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
197
|
+
a.must_equal Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
|
198
|
+
a.wont_equal Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[not-name not-type not-cat])
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe Blather::Stanza::Iq::DiscoInfo::Feature do
|
|
203
|
+
it 'will auto-inherit nodes' do
|
|
204
|
+
n = parse_stanza "<feature var='ipv6' />"
|
|
205
|
+
i = Blather::Stanza::Iq::DiscoInfo::Feature.new n.root
|
|
206
|
+
i.var.must_equal 'ipv6'
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it 'has a var attribute' do
|
|
210
|
+
n = Blather::Stanza::Iq::DiscoInfo::Feature.new 'var'
|
|
211
|
+
n.var.must_equal 'var'
|
|
212
|
+
n.var = :foo
|
|
213
|
+
n.var.must_equal 'foo'
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it 'raises an error if equality is sent a non DiscoInfo::Feature object' do
|
|
217
|
+
a = Blather::Stanza::Iq::DiscoInfo::Feature.new('var')
|
|
218
|
+
lambda { a == 'foo' }.must_raise RuntimeError
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it 'can determine equality' do
|
|
222
|
+
a = Blather::Stanza::Iq::DiscoInfo::Feature.new('var')
|
|
223
|
+
a.must_equal Blather::Stanza::Iq::DiscoInfo::Feature.new('var')
|
|
224
|
+
a.wont_equal Blather::Stanza::Iq::DiscoInfo::Feature.new('not-var')
|
|
225
|
+
end
|
|
226
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
def disco_items_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<iq type='result'
|
|
6
|
+
from='catalog.shakespeare.lit'
|
|
7
|
+
to='romeo@montague.net/orchard'
|
|
8
|
+
id='items2'>
|
|
9
|
+
<query xmlns='http://jabber.org/protocol/disco#items'>
|
|
10
|
+
<item jid='catalog.shakespeare.lit'
|
|
11
|
+
node='books'
|
|
12
|
+
name='Books by and about Shakespeare'/>
|
|
13
|
+
<item jid='catalog.shakespeare.lit'
|
|
14
|
+
node='clothing'
|
|
15
|
+
name='Wear your literary taste with pride'/>
|
|
16
|
+
<item jid='catalog.shakespeare.lit'
|
|
17
|
+
node='music'
|
|
18
|
+
name='Music from the time of Shakespeare'/>
|
|
19
|
+
</query>
|
|
20
|
+
</iq>
|
|
21
|
+
XML
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe Blather::Stanza::Iq::DiscoItems do
|
|
25
|
+
it 'registers itself' do
|
|
26
|
+
Blather::XMPPNode.class_from_registration(:query, 'http://jabber.org/protocol/disco#items').must_equal Blather::Stanza::Iq::DiscoItems
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'must be importable' do
|
|
30
|
+
Blather::XMPPNode.import(parse_stanza(disco_items_xml).root).must_be_instance_of Blather::Stanza::Iq::DiscoItems
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'is constructed properly' do
|
|
34
|
+
n = Blather::Stanza::Iq::DiscoItems.new :get, '/path/to/node'
|
|
35
|
+
n.to = 'to@jid.com'
|
|
36
|
+
n.find("/iq[@to='to@jid.com' and @type='get' and @id='#{n.id}']/ns:query[@node='/path/to/node']", :ns => Blather::Stanza::Iq::DiscoItems.registered_ns).wont_be_empty
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'has a node attribute' do
|
|
40
|
+
n = Blather::Stanza::Iq::DiscoItems.new nil, 'music', []
|
|
41
|
+
n.node.must_equal 'music'
|
|
42
|
+
n.node = :foo
|
|
43
|
+
n.node.must_equal 'foo'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'inherits a list of identities' do
|
|
47
|
+
n = parse_stanza disco_items_xml
|
|
48
|
+
r = Blather::Stanza::Iq::DiscoItems.new.inherit n.root
|
|
49
|
+
r.items.size.must_equal 3
|
|
50
|
+
r.items.map { |i| i.class }.uniq.must_equal [Blather::Stanza::Iq::DiscoItems::Item]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'takes a list of hashes for items' do
|
|
54
|
+
items = [
|
|
55
|
+
{:jid => 'foo@bar/baz', :node => 'node', :name => 'name'},
|
|
56
|
+
{:jid => 'baz@foo/bar', :node => 'node1', :name => 'name1'},
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
control = [ Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
|
60
|
+
Blather::Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
|
61
|
+
|
|
62
|
+
di = Blather::Stanza::Iq::DiscoItems.new nil, nil, items
|
|
63
|
+
di.items.size.must_equal 2
|
|
64
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'takes a list of Item objects as items' do
|
|
68
|
+
control = [ Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
|
69
|
+
Blather::Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
|
70
|
+
|
|
71
|
+
di = Blather::Stanza::Iq::DiscoItems.new nil, nil, control
|
|
72
|
+
di.items.size.must_equal 2
|
|
73
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'takes a single hash as identity' do
|
|
77
|
+
control = [Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name])]
|
|
78
|
+
|
|
79
|
+
di = Blather::Stanza::Iq::DiscoItems.new nil, nil, {:jid => 'foo@bar/baz', :node => 'node', :name => 'name'}
|
|
80
|
+
di.items.size.must_equal 1
|
|
81
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'takes a single identity object as identity' do
|
|
85
|
+
control = [Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name])]
|
|
86
|
+
|
|
87
|
+
di = Blather::Stanza::Iq::DiscoItems.new nil, nil, control.first
|
|
88
|
+
di.items.size.must_equal 1
|
|
89
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'takes a mix of hashes and identity objects as items' do
|
|
93
|
+
items = [
|
|
94
|
+
{:jid => 'foo@bar/baz', :node => 'node', :name => 'name'},
|
|
95
|
+
Blather::Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1]),
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
control = [ Blather::Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
|
99
|
+
Blather::Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
|
100
|
+
|
|
101
|
+
di = Blather::Stanza::Iq::DiscoItems.new nil, nil, items
|
|
102
|
+
di.items.size.must_equal 2
|
|
103
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe Blather::Stanza::Iq::DiscoItems::Item do
|
|
108
|
+
it 'will auto-inherit nodes' do
|
|
109
|
+
n = parse_stanza "<item jid='foo@bar/baz' node='music' name='Music from the time of Shakespeare' />"
|
|
110
|
+
i = Blather::Stanza::Iq::DiscoItems::Item.new n.root
|
|
111
|
+
i.jid.must_equal Blather::JID.new('foo@bar/baz')
|
|
112
|
+
i.node.must_equal 'music'
|
|
113
|
+
i.name.must_equal 'Music from the time of Shakespeare'
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'has a jid attribute' do
|
|
117
|
+
n = Blather::Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz'
|
|
118
|
+
n.jid.must_be_kind_of Blather::JID
|
|
119
|
+
n.jid.must_equal Blather::JID.new('foo@bar/baz')
|
|
120
|
+
n.jid = 'baz@foo/bar'
|
|
121
|
+
n.jid.must_equal Blather::JID.new('baz@foo/bar')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'has a node attribute' do
|
|
125
|
+
n = Blather::Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz', 'music'
|
|
126
|
+
n.node.must_equal 'music'
|
|
127
|
+
n.node = 'book'
|
|
128
|
+
n.node.must_equal 'book'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'has a name attribute' do
|
|
132
|
+
n = Blather::Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz', nil, 'Music from the time of Shakespeare'
|
|
133
|
+
n.name.must_equal 'Music from the time of Shakespeare'
|
|
134
|
+
n.name = 'Books by and about Shakespeare'
|
|
135
|
+
n.name.must_equal 'Books by and about Shakespeare'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'raises an error when compared against a non DiscoItems::Item' do
|
|
139
|
+
a = Blather::Stanza::Iq::DiscoItems::Item.new('foo@bar/baz')
|
|
140
|
+
lambda { a == 'test' }.must_raise RuntimeError
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'can determine equality' do
|
|
144
|
+
a = Blather::Stanza::Iq::DiscoItems::Item.new('foo@bar/baz')
|
|
145
|
+
a.must_equal Blather::Stanza::Iq::DiscoItems::Item.new('foo@bar/baz')
|
|
146
|
+
a.wont_equal Blather::Stanza::Iq::DiscoItems::Item.new('not-foo@bar/baz')
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Iq::Query do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:query, nil).must_equal Blather::Stanza::Iq::Query
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'can be imported' do
|
|
9
|
+
doc = parse_stanza <<-XML
|
|
10
|
+
<iq from='juliet@example.com/balcony' type='set' id='roster_4'>
|
|
11
|
+
<query>
|
|
12
|
+
<item jid='nurse@example.com' subscription='remove'/>
|
|
13
|
+
</query>
|
|
14
|
+
</iq>
|
|
15
|
+
XML
|
|
16
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Iq::Query
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'ensures a query node is present on create' do
|
|
20
|
+
query = Blather::Stanza::Iq::Query.new
|
|
21
|
+
query.xpath('query').wont_be_empty
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'ensures a query node exists when calling #query' do
|
|
25
|
+
query = Blather::Stanza::Iq::Query.new
|
|
26
|
+
query.remove_child :query
|
|
27
|
+
query.xpath('query').must_be_empty
|
|
28
|
+
|
|
29
|
+
query.query.wont_be_nil
|
|
30
|
+
query.xpath('query').wont_be_empty
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
[:get, :set, :result, :error].each do |type|
|
|
34
|
+
it "can be set as \"#{type}\"" do
|
|
35
|
+
query = Blather::Stanza::Iq::Query.new type
|
|
36
|
+
query.type.must_equal type
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'sets type to "result" on reply' do
|
|
41
|
+
query = Blather::Stanza::Iq::Query.new
|
|
42
|
+
query.type.must_equal :get
|
|
43
|
+
reply = query.reply.type.must_equal :result
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'sets type to "result" on reply!' do
|
|
47
|
+
query = Blather::Stanza::Iq::Query.new
|
|
48
|
+
query.type.must_equal :get
|
|
49
|
+
query.reply!
|
|
50
|
+
query.type.must_equal :result
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'can be registered under a namespace' do
|
|
54
|
+
class QueryNs < Blather::Stanza::Iq::Query; register :query_ns, nil, 'query:ns'; end
|
|
55
|
+
Blather::XMPPNode.class_from_registration(:query, 'query:ns').must_equal QueryNs
|
|
56
|
+
query_ns = QueryNs.new
|
|
57
|
+
query_ns.xpath('query').must_be_empty
|
|
58
|
+
query_ns.xpath('ns:query', :ns => 'query:ns').size.must_equal 1
|
|
59
|
+
|
|
60
|
+
query_ns.query
|
|
61
|
+
query_ns.query
|
|
62
|
+
query_ns.xpath('ns:query', :ns => 'query:ns').size.must_equal 1
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
def roster_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<iq to='juliet@example.com/balcony' type='result' id='roster_1'>
|
|
6
|
+
<query xmlns='jabber:iq:roster'>
|
|
7
|
+
<item jid='romeo@example.net'
|
|
8
|
+
name='Romeo'
|
|
9
|
+
subscription='both'>
|
|
10
|
+
<group>Friends</group>
|
|
11
|
+
</item>
|
|
12
|
+
<item jid='mercutio@example.org'
|
|
13
|
+
name='Mercutio'
|
|
14
|
+
subscription='from'>
|
|
15
|
+
<group>Friends</group>
|
|
16
|
+
</item>
|
|
17
|
+
<item jid='benvolio@example.org'
|
|
18
|
+
name='Benvolio'
|
|
19
|
+
subscription='both'>
|
|
20
|
+
<group>Friends</group>
|
|
21
|
+
</item>
|
|
22
|
+
</query>
|
|
23
|
+
</iq>
|
|
24
|
+
XML
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe Blather::Stanza::Iq::Roster do
|
|
28
|
+
it 'registers itself' do
|
|
29
|
+
Blather::XMPPNode.class_from_registration(:query, 'jabber:iq:roster').must_equal Blather::Stanza::Iq::Roster
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'ensures newly inherited items are RosterItem objects' do
|
|
33
|
+
n = parse_stanza roster_xml
|
|
34
|
+
r = Blather::Stanza::Iq::Roster.new.inherit n.root
|
|
35
|
+
r.items.map { |i| i.class }.uniq.must_equal [Blather::Stanza::Iq::Roster::RosterItem]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'can be created with #import' do
|
|
39
|
+
doc = parse_stanza roster_xml
|
|
40
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Iq::Roster
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe Blather::Stanza::Iq::Roster::RosterItem do
|
|
45
|
+
it 'can be initialized with just a Blather::JID' do
|
|
46
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new 'n@d/r'
|
|
47
|
+
i.jid.must_equal Blather::JID.new('n@d/r')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'can be initialized with a name' do
|
|
51
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new nil, 'foobar'
|
|
52
|
+
i.name.must_equal 'foobar'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'can be initialized with a subscription' do
|
|
56
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new nil, nil, :both
|
|
57
|
+
i.subscription.must_equal :both
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'can be initialized with ask (subscription sub-type)' do
|
|
61
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new nil, nil, nil, :subscribe
|
|
62
|
+
i.ask.must_equal :subscribe
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'can be initailized with a hash' do
|
|
66
|
+
control = { :jid => 'j@d/r',
|
|
67
|
+
:name => 'name',
|
|
68
|
+
:subscription => :both,
|
|
69
|
+
:ask => :subscribe }
|
|
70
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new control
|
|
71
|
+
i.jid.must_equal Blather::JID.new(control[:jid])
|
|
72
|
+
i.name.must_equal control[:name]
|
|
73
|
+
i.subscription.must_equal control[:subscription]
|
|
74
|
+
i.ask.must_equal control[:ask]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'inherits a node when initialized with one' do
|
|
78
|
+
n = Blather::XMPPNode.new 'item'
|
|
79
|
+
n[:jid] = 'n@d/r'
|
|
80
|
+
n[:subscription] = 'both'
|
|
81
|
+
|
|
82
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new n
|
|
83
|
+
i.jid.must_equal Blather::JID.new('n@d/r')
|
|
84
|
+
i.subscription.must_equal :both
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'has a #groups helper that gives an array of groups' do
|
|
88
|
+
n = parse_stanza "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
|
89
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new n.root
|
|
90
|
+
i.must_respond_to :groups
|
|
91
|
+
i.groups.sort.must_equal %w[bar baz foo]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'has a helper to set the groups' do
|
|
95
|
+
n = parse_stanza "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
|
96
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new n.root
|
|
97
|
+
i.must_respond_to :groups=
|
|
98
|
+
i.groups.sort.must_equal %w[bar baz foo]
|
|
99
|
+
i.groups = %w[a b c]
|
|
100
|
+
i.groups.sort.must_equal %w[a b c]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'can be easily converted into a proper stanza' do
|
|
104
|
+
xml = "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
|
105
|
+
n = parse_stanza xml
|
|
106
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new n.root
|
|
107
|
+
i.must_respond_to :to_stanza
|
|
108
|
+
s = i.to_stanza
|
|
109
|
+
s.must_be_kind_of Blather::Stanza::Iq::Roster
|
|
110
|
+
s.items.first.jid.must_equal Blather::JID.new('romeo@example.net')
|
|
111
|
+
s.items.first.groups.sort.must_equal %w[bar baz foo]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'has an "attr_accessor" for jid' do
|
|
115
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new
|
|
116
|
+
i.must_respond_to :jid
|
|
117
|
+
i.jid.must_be_nil
|
|
118
|
+
i.must_respond_to :jid=
|
|
119
|
+
i.jid = 'n@d/r'
|
|
120
|
+
i.jid.must_equal Blather::JID.new('n@d/r')
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'has a name attribute' do
|
|
124
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new
|
|
125
|
+
i.name = 'name'
|
|
126
|
+
i.name.must_equal 'name'
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'has a subscription attribute' do
|
|
130
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new
|
|
131
|
+
i.subscription = :both
|
|
132
|
+
i.subscription.must_equal :both
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'has an ask attribute' do
|
|
136
|
+
i = Blather::Stanza::Iq::Roster::RosterItem.new
|
|
137
|
+
i.ask = :subscribe
|
|
138
|
+
i.ask.must_equal :subscribe
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Iq do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:iq, nil).must_equal Blather::Stanza::Iq
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'must be importable' do
|
|
9
|
+
doc = parse_stanza "<iq from='juliet@example.com/balcony' type='set' id='roster_4'></iq>"
|
|
10
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Iq
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'creates a new Iq stanza defaulted as a get' do
|
|
14
|
+
Blather::Stanza::Iq.new.type.must_equal :get
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'sets the id when created' do
|
|
18
|
+
Blather::Stanza::Iq.new.id.wont_be_nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'creates a new Stanza::Iq object on import' do
|
|
22
|
+
Blather::Stanza::Iq.import(Blather::XMPPNode.new('iq')).must_be_kind_of Blather::Stanza::Iq
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'creates a proper object based on its children' do
|
|
26
|
+
n = Blather::XMPPNode.new('iq')
|
|
27
|
+
n << Blather::XMPPNode.new('query', n.document)
|
|
28
|
+
Blather::Stanza::Iq.import(n).must_be_kind_of Blather::Stanza::Iq::Query
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'ensures type is one of Stanza::Iq::VALID_TYPES' do
|
|
32
|
+
lambda { Blather::Stanza::Iq.new :invalid_type_name }.must_raise(Blather::ArgumentError)
|
|
33
|
+
|
|
34
|
+
Blather::Stanza::Iq::VALID_TYPES.each do |valid_type|
|
|
35
|
+
n = Blather::Stanza::Iq.new valid_type
|
|
36
|
+
n.type.must_equal valid_type
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Blather::Stanza::Iq::VALID_TYPES.each do |valid_type|
|
|
41
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
|
42
|
+
Blather::Stanza::Iq.new.must_respond_to :"#{valid_type}?"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|