blather 0.2.1 → 0.2.2
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 +2 -0
- data/README.rdoc +54 -29
- data/Rakefile +94 -13
- data/VERSION.yml +4 -0
- data/examples/drb_client.rb +2 -4
- data/examples/echo.rb +13 -8
- data/examples/pubsub/cli.rb +64 -0
- data/examples/pubsub/ping_pong.rb +18 -0
- data/examples/pubsub/pubsub_dsl.rb +52 -0
- data/examples/pubsub_client.rb +39 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/ext/extconf.rb +65 -0
- data/lib/blather.rb +18 -121
- data/lib/blather/client.rb +13 -0
- data/lib/blather/client/client.rb +165 -0
- data/lib/blather/client/dsl.rb +99 -0
- data/lib/blather/client/pubsub.rb +53 -0
- data/lib/blather/client/pubsub/node.rb +27 -0
- data/lib/blather/core_ext/active_support.rb +1 -0
- data/lib/blather/core_ext/libxml.rb +7 -1
- data/lib/blather/errors.rb +39 -18
- data/lib/blather/errors/sasl_error.rb +87 -0
- data/lib/blather/errors/stanza_error.rb +262 -0
- data/lib/blather/errors/stream_error.rb +253 -0
- data/lib/blather/jid.rb +9 -16
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +7 -4
- data/lib/blather/stanza.rb +19 -25
- data/lib/blather/stanza/disco.rb +9 -0
- data/lib/blather/stanza/disco/disco_info.rb +84 -0
- data/lib/blather/stanza/disco/disco_items.rb +59 -0
- data/lib/blather/stanza/iq.rb +16 -4
- data/lib/blather/stanza/iq/query.rb +6 -4
- data/lib/blather/stanza/iq/roster.rb +38 -38
- data/lib/blather/stanza/pubsub.rb +33 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +52 -0
- data/lib/blather/stanza/pubsub/errors.rb +9 -0
- data/lib/blather/stanza/pubsub/event.rb +21 -0
- data/lib/blather/stanza/pubsub/items.rb +59 -0
- data/lib/blather/stanza/pubsub/owner.rb +9 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +57 -0
- data/lib/blather/stream.rb +125 -57
- data/lib/blather/stream/client.rb +26 -0
- data/lib/blather/stream/component.rb +34 -0
- data/lib/blather/stream/parser.rb +17 -27
- data/lib/blather/stream/resource.rb +21 -24
- data/lib/blather/stream/sasl.rb +60 -37
- data/lib/blather/stream/session.rb +12 -19
- data/lib/blather/stream/stream_handler.rb +39 -0
- data/lib/blather/stream/tls.rb +22 -18
- data/lib/blather/xmpp_node.rb +91 -17
- data/spec/blather/core_ext/libxml_spec.rb +58 -0
- data/spec/blather/errors/sasl_error_spec.rb +56 -0
- data/spec/blather/errors/stanza_error_spec.rb +148 -0
- data/spec/blather/errors/stream_error_spec.rb +114 -0
- data/spec/blather/errors_spec.rb +40 -0
- data/spec/blather/jid_spec.rb +0 -7
- data/spec/blather/roster_item_spec.rb +5 -0
- data/spec/blather/roster_spec.rb +6 -6
- data/spec/blather/stanza/discos/disco_info_spec.rb +207 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +136 -0
- data/spec/blather/stanza/iq/query_spec.rb +9 -2
- data/spec/blather/stanza/iq/roster_spec.rb +117 -1
- data/spec/blather/stanza/iq_spec.rb +29 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +12 -1
- data/spec/blather/stanza/presence_spec.rb +29 -0
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +46 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +63 -0
- data/spec/blather/stanza/pubsub_spec.rb +26 -0
- data/spec/blather/stanza_spec.rb +13 -1
- data/spec/blather/stream/client_spec.rb +787 -0
- data/spec/blather/stream/component_spec.rb +86 -0
- data/spec/blather/xmpp_node_spec.rb +75 -22
- data/spec/fixtures/pubsub.rb +157 -0
- data/spec/spec_helper.rb +6 -14
- metadata +86 -74
- data/CHANGELOG +0 -5
- data/Manifest +0 -47
- data/blather.gemspec +0 -41
- data/lib/blather/stanza/error.rb +0 -31
- data/spec/blather/stream_spec.rb +0 -462
- data/spec/build_safe.rb +0 -20
@@ -0,0 +1,207 @@
|
|
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
|
+
XMPPNode.class_from_registration(:query, 'http://jabber.org/protocol/disco#info').must_equal Blather::Stanza::Iq::DiscoInfo
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'has a node attribute' do
|
27
|
+
n = Blather::Stanza::Iq::DiscoInfo.new nil, 'music', [], []
|
28
|
+
n.node.must_equal 'music'
|
29
|
+
n.node = :foo
|
30
|
+
n.node.must_equal 'foo'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'inherits a list of identities' do
|
34
|
+
n = XML::Document.string disco_info_xml
|
35
|
+
r = Stanza::Iq::DiscoInfo.new.inherit n.root
|
36
|
+
r.identities.size.must_equal 1
|
37
|
+
r.identities.map { |i| i.class }.uniq.must_equal [Stanza::Iq::DiscoInfo::Identity]
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'inherits a list of features' do
|
41
|
+
n = XML::Document.string disco_info_xml
|
42
|
+
r = Stanza::Iq::DiscoInfo.new.inherit n.root
|
43
|
+
r.features.size.must_equal 2
|
44
|
+
r.features.map { |i| i.class }.uniq.must_equal [Stanza::Iq::DiscoInfo::Feature]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'Blather::Stanza::Iq::DiscoInfo identities' do
|
49
|
+
it 'takes a list of hashes for identities' do
|
50
|
+
ids = [
|
51
|
+
{:name => 'name', :type => 'type', :category => 'category'},
|
52
|
+
{:name => 'name1', :type => 'type1', :category => 'category1'},
|
53
|
+
]
|
54
|
+
|
55
|
+
control = [ Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
56
|
+
Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
57
|
+
|
58
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, ids
|
59
|
+
di.identities.size.must_equal 2
|
60
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'takes a list of Identity objects as identities' do
|
64
|
+
control = [ Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
65
|
+
Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
66
|
+
|
67
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, control
|
68
|
+
di.identities.size.must_equal 2
|
69
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'takes a single hash as identity' do
|
73
|
+
control = [Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category])]
|
74
|
+
|
75
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, {:name => 'name', :type => 'type', :category => 'category'}
|
76
|
+
di.identities.size.must_equal 1
|
77
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'takes a single identity object as identity' do
|
81
|
+
control = [Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category])]
|
82
|
+
|
83
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, control.first
|
84
|
+
di.identities.size.must_equal 1
|
85
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'takes a mix of hashes and identity objects as identities' do
|
89
|
+
ids = [
|
90
|
+
{:name => 'name', :type => 'type', :category => 'category'},
|
91
|
+
Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1]),
|
92
|
+
]
|
93
|
+
|
94
|
+
control = [ Stanza::Iq::DiscoInfo::Identity.new(*%w[name type category]),
|
95
|
+
Stanza::Iq::DiscoInfo::Identity.new(*%w[name1 type1 category1])]
|
96
|
+
|
97
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, ids
|
98
|
+
di.identities.size.must_equal 2
|
99
|
+
di.identities.each { |i| control.include?(i).must_equal true }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'Blather::Stanza::Iq::DiscoInfo features' do
|
104
|
+
it 'takes a list of features as strings' do
|
105
|
+
features = %w[feature1 feature2 feature3]
|
106
|
+
control = features.map { |f| Stanza::Iq::DiscoInfo::Feature.new f }
|
107
|
+
|
108
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, [], features
|
109
|
+
di.features.size.must_equal 3
|
110
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'takes a list of features as Feature objects' do
|
114
|
+
features = %w[feature1 feature2 feature3]
|
115
|
+
control = features.map { |f| Stanza::Iq::DiscoInfo::Feature.new f }
|
116
|
+
|
117
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, [], control
|
118
|
+
di.features.size.must_equal 3
|
119
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'takes a single string' do
|
123
|
+
control = [Stanza::Iq::DiscoInfo::Feature.new('feature1')]
|
124
|
+
|
125
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, [], 'feature1'
|
126
|
+
di.features.size.must_equal 1
|
127
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'takes a single Feature object' do
|
131
|
+
control = [Stanza::Iq::DiscoInfo::Feature.new('feature1')]
|
132
|
+
|
133
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, [], control.first
|
134
|
+
di.features.size.must_equal 1
|
135
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'takes a mixed list of features as Feature objects and strings' do
|
139
|
+
features = %w[feature1 feature2 feature3]
|
140
|
+
control = features.map { |f| Stanza::Iq::DiscoInfo::Feature.new f }
|
141
|
+
features[1] = control[1]
|
142
|
+
|
143
|
+
di = Stanza::Iq::DiscoInfo.new nil, nil, [], features
|
144
|
+
di.features.size.must_equal 3
|
145
|
+
di.features.each { |f| control.include?(f).must_equal true }
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'Blather::Stanza::Iq::DiscoInfo::Identity' do
|
150
|
+
it 'will auto-inherit nodes' do
|
151
|
+
n = XML::Document.string "<identity name='Personal Events' type='pep' category='pubsub' node='publish' />"
|
152
|
+
i = Stanza::Iq::DiscoInfo::Identity.new n.root
|
153
|
+
i.name.must_equal 'Personal Events'
|
154
|
+
i.type.must_equal :pep
|
155
|
+
i.category.must_equal :pubsub
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'has a category attribute' do
|
159
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
160
|
+
n.category.must_equal :cat
|
161
|
+
n.category = :foo
|
162
|
+
n.category.must_equal :foo
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'has a type attribute' do
|
166
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
167
|
+
n.type.must_equal :type
|
168
|
+
n.type = :foo
|
169
|
+
n.type.must_equal :foo
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'has a name attribute' do
|
173
|
+
n = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
174
|
+
n.name.must_equal 'name'
|
175
|
+
n.name = :foo
|
176
|
+
n.name.must_equal 'foo'
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'can determine equality' do
|
180
|
+
a = Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
181
|
+
a.must_respond_to :eql?
|
182
|
+
a.must_equal Blather::Stanza::Iq::DiscoInfo::Identity.new(*%w[name type cat])
|
183
|
+
a.wont_equal "<identity name='Personal Events' type='pep' category='pubsub' node='publish' />"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'Blather::Stanza::Iq::DiscoInfo::Feature' do
|
188
|
+
it 'will auto-inherit nodes' do
|
189
|
+
n = XML::Document.string "<feature var='ipv6' />"
|
190
|
+
i = Stanza::Iq::DiscoInfo::Feature.new n.root
|
191
|
+
i.var.must_equal 'ipv6'
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'has a var attribute' do
|
195
|
+
n = Blather::Stanza::Iq::DiscoInfo::Feature.new 'var'
|
196
|
+
n.var.must_equal 'var'
|
197
|
+
n.var = :foo
|
198
|
+
n.var.must_equal 'foo'
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'can determine equality' do
|
202
|
+
a = Blather::Stanza::Iq::DiscoInfo::Feature.new('var')
|
203
|
+
a.must_respond_to :eql?
|
204
|
+
a.must_equal Blather::Stanza::Iq::DiscoInfo::Feature.new('var')
|
205
|
+
a.wont_equal "<feature var='ipv6' />"
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,136 @@
|
|
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
|
+
XMPPNode.class_from_registration(:query, 'http://jabber.org/protocol/disco#items').must_equal Blather::Stanza::Iq::DiscoItems
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has a node attribute' do
|
30
|
+
n = Blather::Stanza::Iq::DiscoItems.new nil, 'music', []
|
31
|
+
n.node.must_equal 'music'
|
32
|
+
n.node = :foo
|
33
|
+
n.node.must_equal 'foo'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'inherits a list of identities' do
|
37
|
+
n = XML::Document.string disco_items_xml
|
38
|
+
r = Stanza::Iq::DiscoItems.new.inherit n.root
|
39
|
+
r.items.size.must_equal 3
|
40
|
+
r.items.map { |i| i.class }.uniq.must_equal [Stanza::Iq::DiscoItems::Item]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'Blather::Stanza::Iq::DiscoItems items' do
|
45
|
+
it 'takes a list of hashes for items' do
|
46
|
+
items = [
|
47
|
+
{:jid => 'foo@bar/baz', :node => 'node', :name => 'name'},
|
48
|
+
{:jid => 'baz@foo/bar', :node => 'node1', :name => 'name1'},
|
49
|
+
]
|
50
|
+
|
51
|
+
control = [ Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
52
|
+
Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
53
|
+
|
54
|
+
di = Stanza::Iq::DiscoItems.new nil, nil, items
|
55
|
+
di.items.size.must_equal 2
|
56
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'takes a list of Item objects as items' do
|
60
|
+
control = [ Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
61
|
+
Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
62
|
+
|
63
|
+
di = Stanza::Iq::DiscoItems.new nil, nil, control
|
64
|
+
di.items.size.must_equal 2
|
65
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'takes a single hash as identity' do
|
69
|
+
control = [Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name])]
|
70
|
+
|
71
|
+
di = Stanza::Iq::DiscoItems.new nil, nil, {:jid => 'foo@bar/baz', :node => 'node', :name => 'name'}
|
72
|
+
di.items.size.must_equal 1
|
73
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'takes a single identity object as identity' do
|
77
|
+
control = [Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name])]
|
78
|
+
|
79
|
+
di = Stanza::Iq::DiscoItems.new nil, nil, control.first
|
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 mix of hashes and identity objects as items' do
|
85
|
+
items = [
|
86
|
+
{:jid => 'foo@bar/baz', :node => 'node', :name => 'name'},
|
87
|
+
Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1]),
|
88
|
+
]
|
89
|
+
|
90
|
+
control = [ Stanza::Iq::DiscoItems::Item.new(*%w[foo@bar/baz node name]),
|
91
|
+
Stanza::Iq::DiscoItems::Item.new(*%w[baz@foo/bar node1 name1])]
|
92
|
+
|
93
|
+
di = Stanza::Iq::DiscoItems.new nil, nil, items
|
94
|
+
di.items.size.must_equal 2
|
95
|
+
di.items.each { |i| control.include?(i).must_equal true }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'Blather::Stanza::Iq::DiscoItems::Item' do
|
100
|
+
it 'will auto-inherit nodes' do
|
101
|
+
n = XML::Document.string "<item jid='foo@bar/baz' node='music' name='Music from the time of Shakespeare' />"
|
102
|
+
i = Stanza::Iq::DiscoItems::Item.new n.root
|
103
|
+
i.jid.must_equal JID.new('foo@bar/baz')
|
104
|
+
i.node.must_equal 'music'
|
105
|
+
i.name.must_equal 'Music from the time of Shakespeare'
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'has a jid attribute' do
|
109
|
+
n = Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz'
|
110
|
+
n.jid.must_be_kind_of JID
|
111
|
+
n.jid.must_equal JID.new('foo@bar/baz')
|
112
|
+
n.jid = 'baz@foo/bar'
|
113
|
+
n.jid.must_equal JID.new('baz@foo/bar')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'has a node attribute' do
|
117
|
+
n = Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz', 'music'
|
118
|
+
n.node.must_equal 'music'
|
119
|
+
n.node = 'book'
|
120
|
+
n.node.must_equal 'book'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'has a name attribute' do
|
124
|
+
n = Stanza::Iq::DiscoItems::Item.new 'foo@bar/baz', nil, 'Music from the time of Shakespeare'
|
125
|
+
n.name.must_equal 'Music from the time of Shakespeare'
|
126
|
+
n.name = 'Books by and about Shakespeare'
|
127
|
+
n.name.must_equal 'Books by and about Shakespeare'
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'can determine equality' do
|
131
|
+
a = Stanza::Iq::DiscoItems::Item.new('foo@bar/baz')
|
132
|
+
a.must_respond_to :eql?
|
133
|
+
a.must_equal Stanza::Iq::DiscoItems::Item.new('foo@bar/baz')
|
134
|
+
a.wont_equal "<item jid='foo@bar/baz' node='music' name='Music from the time of Shakespeare' />"
|
135
|
+
end
|
136
|
+
end
|
@@ -19,13 +19,20 @@ describe 'Blather::Stanza::Iq::Query' do
|
|
19
19
|
query.children.detect { |n| n.element_name == 'query' }.wont_be_nil
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
[:get, :set, :result, :error].each do |type|
|
23
|
+
it "can be set as \"#{type}\"" do
|
24
|
+
query = Stanza::Iq::Query.new type
|
25
|
+
query.type.must_equal type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets type to "result" on reply' do
|
23
30
|
query = Stanza::Iq::Query.new
|
24
31
|
query.type.must_equal :get
|
25
32
|
reply = query.reply.type.must_equal :result
|
26
33
|
end
|
27
34
|
|
28
|
-
it 'sets type to "
|
35
|
+
it 'sets type to "result" on reply!' do
|
29
36
|
query = Stanza::Iq::Query.new
|
30
37
|
query.type.must_equal :get
|
31
38
|
query.reply!
|
@@ -1,7 +1,123 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
2
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
|
+
|
3
27
|
describe 'Blather::Stanza::Iq::Roster' do
|
4
28
|
it 'registers itself' do
|
5
29
|
XMPPNode.class_from_registration(:query, 'jabber:iq:roster').must_equal Stanza::Iq::Roster
|
6
30
|
end
|
7
|
-
|
31
|
+
|
32
|
+
it 'ensures newly inherited items are RosterItem objects' do
|
33
|
+
n = XML::Document.string roster_xml
|
34
|
+
r = Stanza::Iq::Roster.new.inherit n.root
|
35
|
+
r.items.map { |i| i.class }.uniq.must_equal [Stanza::Iq::Roster::RosterItem]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'Blather::Stanza::Iq::Roster::RosterItem' do
|
40
|
+
it 'can be initialized with just a JID' do
|
41
|
+
i = Stanza::Iq::Roster::RosterItem.new 'n@d/r'
|
42
|
+
i.jid.must_equal JID.new('n@d/r')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'can be initialized with a name' do
|
46
|
+
i = Stanza::Iq::Roster::RosterItem.new nil, 'foobar'
|
47
|
+
i.name.must_equal 'foobar'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'can be initialized with a subscription' do
|
51
|
+
i = Stanza::Iq::Roster::RosterItem.new nil, nil, :both
|
52
|
+
i.subscription.must_equal :both
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can be initialized with ask (subscription sub-type)' do
|
56
|
+
i = Stanza::Iq::Roster::RosterItem.new nil, nil, nil, :subscribe
|
57
|
+
i.ask.must_equal :subscribe
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'inherits a node when initialized with one' do
|
61
|
+
n = XMPPNode.new 'item'
|
62
|
+
n['jid'] = 'n@d/r'
|
63
|
+
n['subscription'] = 'both'
|
64
|
+
|
65
|
+
i = Stanza::Iq::Roster::RosterItem.new n
|
66
|
+
i.jid.must_equal JID.new('n@d/r')
|
67
|
+
i.subscription.must_equal :both
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'has a #groups helper that gives an array of groups' do
|
71
|
+
n = XML::Document.string "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
72
|
+
i = Stanza::Iq::Roster::RosterItem.new n.root
|
73
|
+
i.must_respond_to :groups
|
74
|
+
i.groups.sort.must_equal %w[bar baz foo]
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'has a helper to set the groups' do
|
78
|
+
n = XML::Document.string "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
79
|
+
i = Stanza::Iq::Roster::RosterItem.new n.root
|
80
|
+
i.must_respond_to :groups=
|
81
|
+
i.groups.sort.must_equal %w[bar baz foo]
|
82
|
+
i.groups = %w[a b c]
|
83
|
+
i.groups.sort.must_equal %w[a b c]
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'can be easily converted into a proper stanza' do
|
87
|
+
xml = "<item jid='romeo@example.net' subscription='both'><group>foo</group><group>bar</group><group>baz</group></item>"
|
88
|
+
n = XML::Document.string xml
|
89
|
+
i = Stanza::Iq::Roster::RosterItem.new n.root
|
90
|
+
i.must_respond_to :to_stanza
|
91
|
+
s = i.to_stanza
|
92
|
+
s.must_be_kind_of Stanza::Iq::Roster
|
93
|
+
s.items.first.jid.must_equal JID.new('romeo@example.net')
|
94
|
+
s.items.first.groups.sort.must_equal %w[bar baz foo]
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'has an "attr_accessor" for jid' do
|
98
|
+
i = Stanza::Iq::Roster::RosterItem.new
|
99
|
+
i.must_respond_to :jid
|
100
|
+
i.jid.must_be_nil
|
101
|
+
i.must_respond_to :jid=
|
102
|
+
i.jid = 'n@d/r'
|
103
|
+
i.jid.must_equal JID.new('n@d/r')
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'has a name attribute' do
|
107
|
+
i = Stanza::Iq::Roster::RosterItem.new
|
108
|
+
i.name = 'name'
|
109
|
+
i.name.must_equal 'name'
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'has a subscription attribute' do
|
113
|
+
i = Stanza::Iq::Roster::RosterItem.new
|
114
|
+
i.subscription = :both
|
115
|
+
i.subscription.must_equal :both
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'has an ask attribute' do
|
119
|
+
i = Stanza::Iq::Roster::RosterItem.new
|
120
|
+
i.ask = :subscribe
|
121
|
+
i.ask.must_equal :subscribe
|
122
|
+
end
|
123
|
+
end
|