sprsquish-blather 0.1 → 0.2.3
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 +100 -0
- data/Rakefile +110 -0
- data/examples/drb_client.rb +5 -0
- data/examples/echo.rb +18 -0
- data/ext/extconf.rb +65 -0
- data/ext/push_parser.c +231 -0
- data/lib/blather/client.rb +219 -44
- data/lib/blather/{core/sugar.rb → core_ext/active_support.rb} +25 -13
- data/lib/blather/core_ext/libxml.rb +28 -0
- 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/errors.rb +48 -0
- data/lib/blather/{core/jid.rb → jid.rb} +15 -26
- data/lib/blather/{core/roster.rb → roster.rb} +22 -0
- data/lib/blather/{core/roster_item.rb → roster_item.rb} +39 -8
- data/lib/blather/stanza/iq/disco.rb +11 -0
- data/lib/blather/stanza/iq/discos/disco_info.rb +86 -0
- data/lib/blather/stanza/iq/discos/disco_items.rb +61 -0
- data/lib/blather/stanza/iq/query.rb +51 -0
- data/lib/blather/stanza/iq/roster.rb +90 -0
- data/lib/blather/stanza/iq.rb +38 -0
- data/lib/blather/stanza/message.rb +58 -0
- data/lib/blather/stanza/presence/status.rb +78 -0
- data/lib/blather/stanza/presence/subscription.rb +72 -0
- data/lib/blather/stanza/presence.rb +45 -0
- data/lib/blather/stanza.rb +101 -0
- data/lib/blather/stream/client.rb +26 -0
- data/lib/blather/stream/component.rb +34 -0
- data/lib/blather/stream/parser.rb +70 -0
- data/lib/blather/stream/resource.rb +48 -0
- data/lib/blather/stream/sasl.rb +173 -0
- data/lib/blather/stream/session.rb +36 -0
- data/lib/blather/stream/stream_handler.rb +39 -0
- data/lib/blather/stream/tls.rb +33 -0
- data/lib/blather/stream.rb +249 -0
- data/lib/blather/xmpp_node.rb +199 -0
- data/lib/blather.rb +40 -41
- 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/{core/jid_spec.rb → jid_spec.rb} +9 -1
- data/spec/blather/{core/roster_item_spec.rb → roster_item_spec.rb} +6 -1
- data/spec/blather/{core/roster_spec.rb → roster_spec.rb} +16 -6
- data/spec/blather/stanza/iq/discos/disco_info_spec.rb +207 -0
- data/spec/blather/stanza/iq/discos/disco_items_spec.rb +136 -0
- data/spec/blather/stanza/iq/query_spec.rb +34 -0
- data/spec/blather/stanza/iq/roster_spec.rb +123 -0
- data/spec/blather/stanza/iq_spec.rb +40 -0
- data/spec/blather/stanza/message_spec.rb +52 -0
- data/spec/blather/stanza/presence/status_spec.rb +102 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +85 -0
- data/spec/blather/stanza/presence_spec.rb +53 -0
- data/spec/blather/{core/stanza_spec.rb → stanza_spec.rb} +14 -2
- data/spec/blather/stream/client_spec.rb +787 -0
- data/spec/blather/stream/component_spec.rb +86 -0
- data/spec/blather/{core/xmpp_node_spec.rb → xmpp_node_spec.rb} +76 -23
- data/spec/build_safe.rb +20 -0
- data/spec/spec_helper.rb +7 -17
- metadata +79 -59
- data/CHANGELOG +0 -1
- data/blather.gemspec +0 -73
- data/lib/blather/callback.rb +0 -24
- data/lib/blather/core/errors.rb +0 -24
- data/lib/blather/core/stanza.rb +0 -90
- data/lib/blather/core/stream.rb +0 -179
- data/lib/blather/core/xmpp_node.rb +0 -95
- data/lib/blather/extensions/last_activity.rb +0 -57
- data/lib/blather/extensions/version.rb +0 -85
- data/spec/blather/core/stream_spec.rb +0 -263
@@ -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
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Iq::Query' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:query, nil).must_equal Stanza::Iq::Query
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'ensures a query node is present on create' do
|
9
|
+
query = Stanza::Iq::Query.new
|
10
|
+
query.children.detect { |n| n.element_name == 'query' }.wont_be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'ensures a query node exists when calling #query' do
|
14
|
+
query = Stanza::Iq::Query.new
|
15
|
+
query.remove_child :query
|
16
|
+
query.children.detect { |n| n.element_name == 'query' }.must_be_nil
|
17
|
+
|
18
|
+
query.query.wont_be_nil
|
19
|
+
query.children.detect { |n| n.element_name == 'query' }.wont_be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'sets type to "result" on reply' do
|
23
|
+
query = Stanza::Iq::Query.new
|
24
|
+
query.type.must_equal :get
|
25
|
+
reply = query.reply.type.must_equal :result
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'sets type to "result" on reply!' do
|
29
|
+
query = Stanza::Iq::Query.new
|
30
|
+
query.type.must_equal :get
|
31
|
+
query.reply!
|
32
|
+
query.type.must_equal :result
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,123 @@
|
|
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
|
+
XMPPNode.class_from_registration(:query, 'jabber:iq:roster').must_equal Stanza::Iq::Roster
|
30
|
+
end
|
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
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Iq' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:iq, nil).must_equal Stanza::Iq
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'creates a new Iq stanza defaulted as a get' do
|
9
|
+
Stanza::Iq.new.type.must_equal :get
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'wont import non-iq stanzas' do
|
13
|
+
lambda { Stanza::Iq.import(XMPPNode.new('foo')) }.must_raise(Blather::ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'creates a new Stanza::Iq object on import' do
|
17
|
+
Stanza::Iq.import(XMPPNode.new('iq')).must_be_kind_of Stanza::Iq
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'creates a proper object based on its children' do
|
21
|
+
n = XMPPNode.new('iq')
|
22
|
+
n << XMPPNode.new('query')
|
23
|
+
Stanza::Iq.import(n).must_be_kind_of Stanza::Iq::Query
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'ensures type is one of Stanza::Iq::VALID_TYPES' do
|
27
|
+
lambda { Stanza::Iq.new :invalid_type_name }.must_raise(Blather::ArgumentError)
|
28
|
+
|
29
|
+
Stanza::Iq::VALID_TYPES.each do |valid_type|
|
30
|
+
n = Stanza::Iq.new valid_type
|
31
|
+
n.type.must_equal valid_type
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Stanza::Iq::VALID_TYPES.each do |valid_type|
|
36
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
37
|
+
Stanza::Iq.new.must_respond_to :"#{valid_type}?"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Message' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:message, nil).must_equal Stanza::Message
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'provides "attr_accessor" for body' do
|
9
|
+
s = Stanza::Message.new
|
10
|
+
s.body.must_be_nil
|
11
|
+
s.detect { |n| n.element_name == 'body' }.must_be_nil
|
12
|
+
|
13
|
+
s.body = 'test message'
|
14
|
+
s.body.wont_be_nil
|
15
|
+
s.detect { |n| n.element_name == 'body' }.wont_be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'provides "attr_accessor" for subject' do
|
19
|
+
s = Stanza::Message.new
|
20
|
+
s.subject.must_be_nil
|
21
|
+
s.detect { |n| n.element_name == 'subject' }.must_be_nil
|
22
|
+
|
23
|
+
s.subject = 'test subject'
|
24
|
+
s.subject.wont_be_nil
|
25
|
+
s.detect { |n| n.element_name == 'subject' }.wont_be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'provides "attr_accessor" for thread' do
|
29
|
+
s = Stanza::Message.new
|
30
|
+
s.thread.must_be_nil
|
31
|
+
s.detect { |n| n.element_name == 'thread' }.must_be_nil
|
32
|
+
|
33
|
+
s.thread = 1234
|
34
|
+
s.thread.wont_be_nil
|
35
|
+
s.detect { |n| n.element_name == 'thread' }.wont_be_nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'ensures type is one of Stanza::Message::VALID_TYPES' do
|
39
|
+
lambda { Stanza::Message.new nil, nil, :invalid_type_name }.must_raise(Blather::ArgumentError)
|
40
|
+
|
41
|
+
Stanza::Message::VALID_TYPES.each do |valid_type|
|
42
|
+
msg = Stanza::Message.new nil, nil, valid_type
|
43
|
+
msg.type.must_equal valid_type
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Stanza::Message::VALID_TYPES.each do |valid_type|
|
48
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
49
|
+
Stanza::Message.new.must_respond_to :"#{valid_type}?"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Presence::Status' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:status, nil).must_equal Stanza::Presence::Status
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'can set state on creation' do
|
9
|
+
status = Stanza::Presence::Status.new :away
|
10
|
+
status.state.must_equal :away
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can set a message on creation' do
|
14
|
+
status = Stanza::Presence::Status.new nil, 'Say hello!'
|
15
|
+
status.message.must_equal 'Say hello!'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'ensures type is nil or :unavailable' do
|
19
|
+
status = Stanza::Presence::Status.new
|
20
|
+
lambda { status.type = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
21
|
+
|
22
|
+
[nil, :unavailable].each do |valid_type|
|
23
|
+
status.type = valid_type
|
24
|
+
status.type.must_equal valid_type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'ensures state is one of Presence::Status::VALID_STATES' do
|
29
|
+
status = Stanza::Presence::Status.new
|
30
|
+
lambda { status.state = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
31
|
+
|
32
|
+
Stanza::Presence::Status::VALID_STATES.each do |valid_state|
|
33
|
+
status.state = valid_state
|
34
|
+
status.state.must_equal valid_state
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns :available if state is nil' do
|
39
|
+
Stanza::Presence::Status.new.state.must_equal :available
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns :unavailable if type is :unavailable' do
|
43
|
+
status = Stanza::Presence::Status.new
|
44
|
+
status.type = :unavailable
|
45
|
+
status.state.must_equal :unavailable
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'ensures priority is not greater than 127' do
|
49
|
+
lambda { Stanza::Presence::Status.new.priority = 128 }.must_raise(Blather::ArgumentError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'ensures priority is not less than -128' do
|
53
|
+
lambda { Stanza::Presence::Status.new.priority = -129 }.must_raise(Blather::ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'has "attr_accessor" for priority' do
|
57
|
+
status = Stanza::Presence::Status.new
|
58
|
+
status.priority.must_equal 0
|
59
|
+
|
60
|
+
status.priority = 10
|
61
|
+
status.children.detect { |n| n.element_name == 'priority' }.wont_be_nil
|
62
|
+
status.priority.must_equal 10
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'has "attr_accessor" for message' do
|
66
|
+
status = Stanza::Presence::Status.new
|
67
|
+
status.message.must_be_nil
|
68
|
+
|
69
|
+
status.message = 'new message'
|
70
|
+
status.children.detect { |n| n.element_name == 'status' }.wont_be_nil
|
71
|
+
status.message.must_equal 'new message'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'must be comparable by priority' do
|
75
|
+
jid = JID.new 'a@b/c'
|
76
|
+
|
77
|
+
status1 = Stanza::Presence::Status.new
|
78
|
+
status1.from = jid
|
79
|
+
|
80
|
+
status2 = Stanza::Presence::Status.new
|
81
|
+
status2.from = jid
|
82
|
+
|
83
|
+
status1.priority = 1
|
84
|
+
status2.priority = -1
|
85
|
+
(status1 <=> status2).must_equal 1
|
86
|
+
(status2 <=> status1).must_equal -1
|
87
|
+
|
88
|
+
status2.priority = 1
|
89
|
+
(status1 <=> status2).must_equal 0
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises an argument error if compared to a status with a different JID' do
|
93
|
+
status1 = Stanza::Presence::Status.new
|
94
|
+
status1.from = 'a@b/c'
|
95
|
+
|
96
|
+
status2 = Stanza::Presence::Status.new
|
97
|
+
status2.from = 'd@e/f'
|
98
|
+
|
99
|
+
lambda { status1 <=> status2 }.must_raise(Blather::ArgumentError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Presence::Subscription' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:subscription, nil).must_equal Stanza::Presence::Subscription
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'can set to on creation' do
|
9
|
+
sub = Stanza::Presence::Subscription.new 'a@b'
|
10
|
+
sub.to.to_s.must_equal 'a@b'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can set a type on creation' do
|
14
|
+
sub = Stanza::Presence::Subscription.new nil, :subscribed
|
15
|
+
sub.type.must_equal :subscribed
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'strips JIDs when setting #to' do
|
19
|
+
sub = Stanza::Presence::Subscription.new 'a@b/c'
|
20
|
+
sub.to.to_s.must_equal 'a@b'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'generates an approval using #approve!' do
|
24
|
+
jid = JID.new 'a@b'
|
25
|
+
sub = Stanza::Presence::Subscription.new
|
26
|
+
sub.from = jid
|
27
|
+
sub.approve!
|
28
|
+
sub.to.must_equal jid
|
29
|
+
sub.type.must_equal :subscribed
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'generates a refusal using #refuse!' do
|
33
|
+
jid = JID.new 'a@b'
|
34
|
+
sub = Stanza::Presence::Subscription.new
|
35
|
+
sub.from = jid
|
36
|
+
sub.refuse!
|
37
|
+
sub.to.must_equal jid
|
38
|
+
sub.type.must_equal :unsubscribed
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'generates an unsubscript using #unsubscribe!' do
|
42
|
+
jid = JID.new 'a@b'
|
43
|
+
sub = Stanza::Presence::Subscription.new
|
44
|
+
sub.from = jid
|
45
|
+
sub.unsubscribe!
|
46
|
+
sub.to.must_equal jid
|
47
|
+
sub.type.must_equal :unsubscribe
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'generates a cancellation using #cancel!' do
|
51
|
+
jid = JID.new 'a@b'
|
52
|
+
sub = Stanza::Presence::Subscription.new
|
53
|
+
sub.from = jid
|
54
|
+
sub.cancel!
|
55
|
+
sub.to.must_equal jid
|
56
|
+
sub.type.must_equal :unsubscribed
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'generates a request using #request!' do
|
60
|
+
jid = JID.new 'a@b'
|
61
|
+
sub = Stanza::Presence::Subscription.new
|
62
|
+
sub.from = jid
|
63
|
+
sub.request!
|
64
|
+
sub.to.must_equal jid
|
65
|
+
sub.type.must_equal :subscribe
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'has a #request? helper' do
|
69
|
+
sub = Stanza::Presence::Subscription.new
|
70
|
+
sub.must_respond_to :request?
|
71
|
+
sub.type = :subscribe
|
72
|
+
sub.request?.must_equal true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "will inherit only another node's attributes" do
|
76
|
+
inheritable = XMPPNode.new 'foo'
|
77
|
+
inheritable.attributes[:bar] = 'baz'
|
78
|
+
|
79
|
+
sub = Stanza::Presence::Subscription.new
|
80
|
+
sub.must_respond_to :inherit
|
81
|
+
|
82
|
+
sub.inherit inheritable
|
83
|
+
sub.attributes[:bar].must_equal 'baz'
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
2
|
+
|
3
|
+
describe 'Blather::Stanza::Presence' do
|
4
|
+
it 'registers itself' do
|
5
|
+
XMPPNode.class_from_registration(:presence, nil).must_equal Stanza::Presence
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'ensures type is one of Stanza::Presence::VALID_TYPES' do
|
9
|
+
presence = Stanza::Presence.new
|
10
|
+
lambda { presence.type = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
11
|
+
|
12
|
+
Stanza::Presence::VALID_TYPES.each do |valid_type|
|
13
|
+
presence.type = valid_type
|
14
|
+
presence.type.must_equal valid_type
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Stanza::Presence::VALID_TYPES.each do |valid_type|
|
19
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
20
|
+
Stanza::Presence.new.must_respond_to :"#{valid_type}?"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'creates a Status object when importing a node with type == nil' do
|
25
|
+
s = Stanza::Presence.import(XMPPNode.new)
|
26
|
+
s.must_be_kind_of Stanza::Presence::Status
|
27
|
+
s.state.must_equal :available
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'creates a Status object when importing a node with type == "unavailable"' do
|
31
|
+
n = XMPPNode.new
|
32
|
+
n.attributes[:type] = :unavailable
|
33
|
+
s = Stanza::Presence.import(n)
|
34
|
+
s.must_be_kind_of Stanza::Presence::Status
|
35
|
+
s.state.must_equal :unavailable
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'creates a Subscription object when importing a node with type == "subscribe"' do
|
39
|
+
n = XMPPNode.new
|
40
|
+
n.attributes[:type] = :subscribe
|
41
|
+
s = Stanza::Presence.import(n)
|
42
|
+
s.must_be_kind_of Stanza::Presence::Subscription
|
43
|
+
s.type.must_equal :subscribe
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'creates a Presence object when importing a node with type equal to something unkown' do
|
47
|
+
n = XMPPNode.new
|
48
|
+
n.attributes[:type] = :foo
|
49
|
+
s = Stanza::Presence.import(n)
|
50
|
+
s.must_be_kind_of Stanza::Presence
|
51
|
+
s.type.must_equal :foo
|
52
|
+
end
|
53
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), *%w[..
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. spec_helper])
|
2
2
|
|
3
3
|
describe 'Blather::Stanza' do
|
4
4
|
it 'provides .next_id helper for generating new IDs' do
|
5
|
-
proc { Stanza.next_id }.must_change 'Stanza'
|
5
|
+
proc { Stanza.next_id }.must_change 'Stanza.next_id'
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'can import a node' do
|
@@ -92,4 +92,16 @@ describe 'Blather::Stanza' do
|
|
92
92
|
s.type.wont_be_nil
|
93
93
|
s['type'].wont_be_nil
|
94
94
|
end
|
95
|
+
|
96
|
+
it 'can be converted into an error by error name' do
|
97
|
+
s = Stanza.new('message')
|
98
|
+
err = s.as_error 'internal-server-error', 'cancel'
|
99
|
+
err.must_be_instance_of StanzaError::InternalServerError
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'can be converted into an error by error class' do
|
103
|
+
s = Stanza.new('message')
|
104
|
+
err = s.as_error StanzaError::InternalServerError, 'cancel'
|
105
|
+
err.must_be_instance_of StanzaError::InternalServerError
|
106
|
+
end
|
95
107
|
end
|