tp-blather 0.8.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/.autotest +13 -0
- data/.gemtest +0 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +249 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE +22 -0
- data/README.md +413 -0
- data/Rakefile +20 -0
- data/TODO.md +2 -0
- data/blather.gemspec +51 -0
- data/examples/certs/README +20 -0
- data/examples/certs/ca-bundle.crt +3987 -0
- data/examples/echo.rb +19 -0
- data/examples/execute.rb +17 -0
- data/examples/ping_pong.rb +38 -0
- data/examples/print_hierarchy.rb +77 -0
- data/examples/rosterprint.rb +15 -0
- data/examples/stream_only.rb +28 -0
- data/examples/trusted_echo.rb +21 -0
- data/examples/xmpp4r/echo.rb +36 -0
- data/lib/blather.rb +112 -0
- data/lib/blather/cert_store.rb +53 -0
- data/lib/blather/client.rb +95 -0
- data/lib/blather/client/client.rb +345 -0
- data/lib/blather/client/dsl.rb +320 -0
- data/lib/blather/client/dsl/pubsub.rb +174 -0
- data/lib/blather/core_ext/eventmachine.rb +125 -0
- data/lib/blather/core_ext/ipaddr.rb +20 -0
- data/lib/blather/errors.rb +69 -0
- data/lib/blather/errors/sasl_error.rb +44 -0
- data/lib/blather/errors/stanza_error.rb +110 -0
- data/lib/blather/errors/stream_error.rb +84 -0
- data/lib/blather/file_transfer.rb +107 -0
- data/lib/blather/file_transfer/ibb.rb +68 -0
- data/lib/blather/file_transfer/s5b.rb +114 -0
- data/lib/blather/jid.rb +141 -0
- data/lib/blather/roster.rb +118 -0
- data/lib/blather/roster_item.rb +146 -0
- data/lib/blather/stanza.rb +167 -0
- data/lib/blather/stanza/disco.rb +32 -0
- data/lib/blather/stanza/disco/capabilities.rb +161 -0
- data/lib/blather/stanza/disco/disco_info.rb +205 -0
- data/lib/blather/stanza/disco/disco_items.rb +134 -0
- data/lib/blather/stanza/iq.rb +144 -0
- data/lib/blather/stanza/iq/command.rb +339 -0
- data/lib/blather/stanza/iq/ibb.rb +86 -0
- data/lib/blather/stanza/iq/ping.rb +50 -0
- data/lib/blather/stanza/iq/query.rb +53 -0
- data/lib/blather/stanza/iq/roster.rb +185 -0
- data/lib/blather/stanza/iq/s5b.rb +208 -0
- data/lib/blather/stanza/iq/si.rb +415 -0
- data/lib/blather/stanza/iq/vcard.rb +149 -0
- data/lib/blather/stanza/message.rb +428 -0
- data/lib/blather/stanza/message/muc_user.rb +119 -0
- data/lib/blather/stanza/muc/muc_user_base.rb +54 -0
- data/lib/blather/stanza/presence.rb +172 -0
- data/lib/blather/stanza/presence/c.rb +100 -0
- data/lib/blather/stanza/presence/muc.rb +35 -0
- data/lib/blather/stanza/presence/muc_user.rb +147 -0
- data/lib/blather/stanza/presence/status.rb +218 -0
- data/lib/blather/stanza/presence/subscription.rb +100 -0
- data/lib/blather/stanza/pubsub.rb +119 -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 +139 -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 +135 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +83 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +84 -0
- data/lib/blather/stanza/pubsub_owner.rb +51 -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/x.rb +416 -0
- data/lib/blather/stream.rb +266 -0
- data/lib/blather/stream/client.rb +32 -0
- data/lib/blather/stream/component.rb +39 -0
- data/lib/blather/stream/features.rb +70 -0
- data/lib/blather/stream/features/register.rb +38 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/features/sasl.rb +190 -0
- data/lib/blather/stream/features/session.rb +45 -0
- data/lib/blather/stream/features/tls.rb +29 -0
- data/lib/blather/stream/parser.rb +102 -0
- data/lib/blather/version.rb +3 -0
- data/lib/blather/xmpp_node.rb +94 -0
- data/spec/blather/client/client_spec.rb +687 -0
- data/spec/blather/client/dsl/pubsub_spec.rb +492 -0
- data/spec/blather/client/dsl_spec.rb +266 -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/file_transfer_spec.rb +135 -0
- data/spec/blather/jid_spec.rb +87 -0
- data/spec/blather/roster_item_spec.rb +134 -0
- data/spec/blather/roster_spec.rb +107 -0
- data/spec/blather/stanza/discos/disco_info_spec.rb +247 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +154 -0
- data/spec/blather/stanza/iq/command_spec.rb +206 -0
- data/spec/blather/stanza/iq/ibb_spec.rb +124 -0
- data/spec/blather/stanza/iq/ping_spec.rb +45 -0
- data/spec/blather/stanza/iq/query_spec.rb +64 -0
- data/spec/blather/stanza/iq/roster_spec.rb +139 -0
- data/spec/blather/stanza/iq/s5b_spec.rb +57 -0
- data/spec/blather/stanza/iq/si_spec.rb +98 -0
- data/spec/blather/stanza/iq/vcard_spec.rb +93 -0
- data/spec/blather/stanza/iq_spec.rb +61 -0
- data/spec/blather/stanza/message/muc_user_spec.rb +152 -0
- data/spec/blather/stanza/message_spec.rb +282 -0
- data/spec/blather/stanza/presence/c_spec.rb +56 -0
- data/spec/blather/stanza/presence/muc_spec.rb +37 -0
- data/spec/blather/stanza/presence/muc_user_spec.rb +83 -0
- data/spec/blather/stanza/presence/status_spec.rb +144 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +102 -0
- data/spec/blather/stanza/presence_spec.rb +125 -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 +98 -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 +74 -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 +68 -0
- data/spec/blather/stanza/x_spec.rb +231 -0
- data/spec/blather/stanza_spec.rb +134 -0
- data/spec/blather/stream/client_spec.rb +1090 -0
- data/spec/blather/stream/component_spec.rb +108 -0
- data/spec/blather/stream/parser_spec.rb +152 -0
- data/spec/blather/stream/ssl_spec.rb +32 -0
- data/spec/blather/xmpp_node_spec.rb +47 -0
- data/spec/blather_spec.rb +34 -0
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +17 -0
- data/yard/templates/default/class/html/handlers.erb +18 -0
- data/yard/templates/default/class/setup.rb +10 -0
- data/yard/templates/default/class/text/handlers.erb +1 -0
- metadata +459 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blather::BlatherError do
|
|
4
|
+
it 'is handled by :error' do
|
|
5
|
+
Blather::BlatherError.new.handler_hierarchy.should == [:error]
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe 'Blather::ParseError' do
|
|
10
|
+
before { @error = Blather::ParseError.new('</generate-parse-error>"') }
|
|
11
|
+
|
|
12
|
+
it 'is registers with the handler hierarchy' do
|
|
13
|
+
@error.handler_hierarchy.should == [:parse_error, :error]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'contains the error message' do
|
|
17
|
+
@error.should respond_to :message
|
|
18
|
+
@error.message.should == '</generate-parse-error>"'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe 'Blather::UnknownResponse' do
|
|
23
|
+
before { @error = Blather::UnknownResponse.new(Blather::XMPPNode.new('foo-bar')) }
|
|
24
|
+
|
|
25
|
+
it 'is registers with the handler hierarchy' do
|
|
26
|
+
@error.handler_hierarchy.should == [:unknown_response_error, :error]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'holds on to a copy of the failure node' do
|
|
30
|
+
@error.should respond_to :node
|
|
31
|
+
@error.node.element_name.should == 'foo-bar'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'blather/client/dsl'
|
|
3
|
+
|
|
4
|
+
module MockFileReceiver
|
|
5
|
+
def post_init
|
|
6
|
+
end
|
|
7
|
+
def receive_data(data)
|
|
8
|
+
end
|
|
9
|
+
def unbind
|
|
10
|
+
end
|
|
11
|
+
def send(data, params)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def si_xml
|
|
16
|
+
<<-XML
|
|
17
|
+
<iq type='set' id='offer1' to='juliet@capulet.com/balcony' from='romeo@montague.net/orchard'>
|
|
18
|
+
<si xmlns='http://jabber.org/protocol/si'
|
|
19
|
+
id='a0'
|
|
20
|
+
mime-type='text/plain'
|
|
21
|
+
profile='http://jabber.org/protocol/si/profile/file-transfer'>
|
|
22
|
+
<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'
|
|
23
|
+
name='test.txt'
|
|
24
|
+
size='1022'>
|
|
25
|
+
<range/>
|
|
26
|
+
</file>
|
|
27
|
+
<feature xmlns='http://jabber.org/protocol/feature-neg'>
|
|
28
|
+
<x xmlns='jabber:x:data' type='form'>
|
|
29
|
+
<field var='stream-method' type='list-single'>
|
|
30
|
+
<option><value>http://jabber.org/protocol/bytestreams</value></option>
|
|
31
|
+
<option><value>http://jabber.org/protocol/ibb</value></option>
|
|
32
|
+
</field>
|
|
33
|
+
</x>
|
|
34
|
+
</feature>
|
|
35
|
+
</si>
|
|
36
|
+
</iq>
|
|
37
|
+
XML
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe Blather::FileTransfer do
|
|
41
|
+
before do
|
|
42
|
+
@host = 'host.name'
|
|
43
|
+
@client = Blather::Client.setup Blather::JID.new('n@d/r'), 'pass'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'can select ibb' do
|
|
47
|
+
iq = Blather::XMPPNode.parse(si_xml)
|
|
48
|
+
|
|
49
|
+
@client.stubs(:write).with do |answer|
|
|
50
|
+
answer.si.feature.x.field('stream-method').value.should == Blather::Stanza::Iq::Ibb::NS_IBB
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
transfer = Blather::FileTransfer.new(@client, iq)
|
|
55
|
+
transfer.allow_s5b = false
|
|
56
|
+
transfer.allow_ibb = true
|
|
57
|
+
transfer.accept(MockFileReceiver)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'can select s5b' do
|
|
61
|
+
iq = Blather::XMPPNode.parse(si_xml)
|
|
62
|
+
|
|
63
|
+
@client.stubs(:write).with do |answer|
|
|
64
|
+
answer.si.feature.x.field('stream-method').value.should == Blather::Stanza::Iq::S5b::NS_S5B
|
|
65
|
+
true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
transfer = Blather::FileTransfer.new(@client, iq)
|
|
69
|
+
transfer.allow_s5b = true
|
|
70
|
+
transfer.allow_ibb = false
|
|
71
|
+
transfer.accept(MockFileReceiver)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'can allow s5b private ips' do
|
|
75
|
+
iq = Blather::XMPPNode.parse(si_xml)
|
|
76
|
+
|
|
77
|
+
@client.stubs(:write).with do |answer|
|
|
78
|
+
answer.si.feature.x.field('stream-method').value.should == Blather::Stanza::Iq::S5b::NS_S5B
|
|
79
|
+
true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
transfer = Blather::FileTransfer.new(@client, iq)
|
|
83
|
+
transfer.allow_s5b = true
|
|
84
|
+
transfer.allow_private_ips = true
|
|
85
|
+
transfer.allow_ibb = false
|
|
86
|
+
transfer.accept(MockFileReceiver)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'can response no-valid-streams' do
|
|
90
|
+
iq = Blather::XMPPNode.parse(si_xml)
|
|
91
|
+
|
|
92
|
+
@client.stubs(:write).with do |answer|
|
|
93
|
+
answer.find_first('error')['type'].should == "cancel"
|
|
94
|
+
answer.find_first('.//ns:no-valid-streams', :ns => 'http://jabber.org/protocol/si').should_not be_nil
|
|
95
|
+
true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
transfer = Blather::FileTransfer.new(@client, iq)
|
|
99
|
+
transfer.allow_s5b = false
|
|
100
|
+
transfer.allow_ibb = false
|
|
101
|
+
transfer.accept(MockFileReceiver)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'can decline transfer' do
|
|
105
|
+
iq = Blather::XMPPNode.parse(si_xml)
|
|
106
|
+
|
|
107
|
+
@client.stubs(:write).with do |answer|
|
|
108
|
+
answer.find_first('error')['type'].should == "cancel"
|
|
109
|
+
answer.find_first('.//ns:forbidden', :ns => 'urn:ietf:params:xml:ns:xmpp-stanzas').should_not be_nil
|
|
110
|
+
answer.find_first('.//ns:text', :ns => 'urn:ietf:params:xml:ns:xmpp-stanzas').content.should == "Offer declined"
|
|
111
|
+
true
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
transfer = Blather::FileTransfer.new(@client, iq)
|
|
115
|
+
transfer.decline
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'can s5b post_init include the handler' do
|
|
119
|
+
class TestS5B < Blather::FileTransfer::S5b::SocketConnection
|
|
120
|
+
def initialize()
|
|
121
|
+
super("0.0.0.0", 1, MockFileReceiver, nil)
|
|
122
|
+
restore_methods
|
|
123
|
+
self.post_init()
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.new(*args)
|
|
127
|
+
allocate.instance_eval do
|
|
128
|
+
initialize(*args)
|
|
129
|
+
self
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
lambda { TestS5B.new }.should_not raise_error
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blather::JID do
|
|
4
|
+
it 'does nothing if creaded from Blather::JID' do
|
|
5
|
+
jid = Blather::JID.new 'n@d/r'
|
|
6
|
+
Blather::JID.new(jid).object_id.should == jid.object_id
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'creates a new Blather::JID from (n,d,r)' do
|
|
10
|
+
jid = Blather::JID.new('n', 'd', 'r')
|
|
11
|
+
jid.node.should == 'n'
|
|
12
|
+
jid.domain.should == 'd'
|
|
13
|
+
jid.resource.should == 'r'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'creates a new Blather::JID from (n,d)' do
|
|
17
|
+
jid = Blather::JID.new('n', 'd')
|
|
18
|
+
jid.node.should == 'n'
|
|
19
|
+
jid.domain.should == 'd'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'creates a new Blather::JID from (n@d)' do
|
|
23
|
+
jid = Blather::JID.new('n@d')
|
|
24
|
+
jid.node.should == 'n'
|
|
25
|
+
jid.domain.should == 'd'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'creates a new Blather::JID from (n@d/r)' do
|
|
29
|
+
jid = Blather::JID.new('n@d/r')
|
|
30
|
+
jid.node.should == 'n'
|
|
31
|
+
jid.domain.should == 'd'
|
|
32
|
+
jid.resource.should == 'r'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'requires at least a node' do
|
|
36
|
+
proc { Blather::JID.new }.should raise_error ::ArgumentError
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'ensures length of node is no more than 1023 characters' do
|
|
40
|
+
proc { Blather::JID.new('n'*1024) }.should raise_error Blather::ArgumentError
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'ensures length of domain is no more than 1023 characters' do
|
|
44
|
+
proc { Blather::JID.new('n', 'd'*1024) }.should raise_error Blather::ArgumentError
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'ensures length of resource is no more than 1023 characters' do
|
|
48
|
+
proc { Blather::JID.new('n', 'd', 'r'*1024) }.should raise_error Blather::ArgumentError
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'compares Blather::JIDs' do
|
|
52
|
+
(Blather::JID.new('a@b/c') <=> Blather::JID.new('d@e/f')).should == -1
|
|
53
|
+
(Blather::JID.new('a@b/c') <=> Blather::JID.new('a@b/c')).should == 0
|
|
54
|
+
(Blather::JID.new('d@e/f') <=> Blather::JID.new('a@b/c')).should == 1
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'checks for equality' do
|
|
58
|
+
(Blather::JID.new('n@d/r') == Blather::JID.new('n@d/r')).should == true
|
|
59
|
+
Blather::JID.new('n@d/r').eql?(Blather::JID.new('n@d/r')).should == true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'will strip' do
|
|
63
|
+
jid = Blather::JID.new('n@d/r')
|
|
64
|
+
jid.stripped.should == Blather::JID.new('n@d')
|
|
65
|
+
jid.should == Blather::JID.new('n@d/r')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'will strip itself' do
|
|
69
|
+
jid = Blather::JID.new('n@d/r')
|
|
70
|
+
jid.strip!
|
|
71
|
+
jid.should == Blather::JID.new('n@d')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'has a string representation' do
|
|
75
|
+
Blather::JID.new('n@d/r').to_s.should == 'n@d/r'
|
|
76
|
+
Blather::JID.new('n', 'd', 'r').to_s.should == 'n@d/r'
|
|
77
|
+
Blather::JID.new('n', 'd').to_s.should == 'n@d'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'provides a #stripped? helper' do
|
|
81
|
+
jid = Blather::JID.new 'a@b/c'
|
|
82
|
+
jid.should respond_to :stripped?
|
|
83
|
+
jid.stripped?.should_not equal true
|
|
84
|
+
jid.strip!
|
|
85
|
+
jid.stripped?.should == true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blather::RosterItem do
|
|
4
|
+
it 'can be initialized with Blather::JID' do
|
|
5
|
+
jid = Blather::JID.new(jid)
|
|
6
|
+
i = Blather::RosterItem.new jid
|
|
7
|
+
i.jid.should == jid
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'can be initialized with an Iq::RosterItem' do
|
|
11
|
+
jid = 'n@d/r'
|
|
12
|
+
i = Blather::RosterItem.new Blather::Stanza::Iq::Roster::RosterItem.new(jid)
|
|
13
|
+
i.jid.should == Blather::JID.new(jid).stripped
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'can be initialized with a string' do
|
|
17
|
+
jid = 'n@d/r'
|
|
18
|
+
i = Blather::RosterItem.new jid
|
|
19
|
+
i.jid.should == Blather::JID.new(jid).stripped
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'returns the same object when intialized with a Blather::RosterItem' do
|
|
23
|
+
control = Blather::RosterItem.new 'n@d/r'
|
|
24
|
+
Blather::RosterItem.new(control).should be control
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'has a Blather::JID setter that strips the Blather::JID' do
|
|
28
|
+
jid = Blather::JID.new('n@d/r')
|
|
29
|
+
i = Blather::RosterItem.new nil
|
|
30
|
+
i.jid = jid
|
|
31
|
+
i.jid.should == jid.stripped
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'has a subscription setter that forces a symbol' do
|
|
35
|
+
i = Blather::RosterItem.new nil
|
|
36
|
+
i.subscription = 'remove'
|
|
37
|
+
i.subscription.should == :remove
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'forces the type of subscription' do
|
|
41
|
+
proc { Blather::RosterItem.new(nil).subscription = 'foo' }.should raise_error Blather::ArgumentError
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'returns :none if the subscription field is blank' do
|
|
45
|
+
Blather::RosterItem.new(nil).subscription.should == :none
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'ensure #ask is a symbol' do
|
|
49
|
+
i = Blather::RosterItem.new(nil)
|
|
50
|
+
i.ask = 'subscribe'
|
|
51
|
+
i.ask.should == :subscribe
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'forces #ask to be :subscribe or nothing at all' do
|
|
55
|
+
proc { Blather::RosterItem.new(nil).ask = 'foo' }.should raise_error Blather::ArgumentError
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'generates a stanza with #to_stanza' do
|
|
59
|
+
jid = Blather::JID.new('n@d/r')
|
|
60
|
+
i = Blather::RosterItem.new jid
|
|
61
|
+
s = i.to_stanza
|
|
62
|
+
s.should be_kind_of Blather::Stanza::Iq::Roster
|
|
63
|
+
s.items.first.jid.should == jid.stripped
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'returns status based on priority' do
|
|
67
|
+
setup_item_with_presences
|
|
68
|
+
@i.status.should == @p3
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'returns status based on priority and state' do
|
|
72
|
+
setup_item_with_presences
|
|
73
|
+
|
|
74
|
+
@p4 = Blather::Stanza::Presence::Status.new
|
|
75
|
+
@p4.type = :unavailable
|
|
76
|
+
@p4.from = 'n@d/d'
|
|
77
|
+
@p4.priority = 15
|
|
78
|
+
@i.status = @p4
|
|
79
|
+
|
|
80
|
+
@i.status.should == @p3
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'returns status based on resource' do
|
|
84
|
+
setup_item_with_presences
|
|
85
|
+
@i.status('a').should == @p
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def setup_item_with_presences
|
|
89
|
+
@jid = Blather::JID.new('n@d/r')
|
|
90
|
+
@i = Blather::RosterItem.new @jid
|
|
91
|
+
|
|
92
|
+
@p = Blather::Stanza::Presence::Status.new(:away)
|
|
93
|
+
@p.from = 'n@d/a'
|
|
94
|
+
@p.priority = 0
|
|
95
|
+
|
|
96
|
+
@p2 = Blather::Stanza::Presence::Status.new(:dnd)
|
|
97
|
+
@p2.from = 'n@d/b'
|
|
98
|
+
@p2.priority = -1
|
|
99
|
+
|
|
100
|
+
@p3 = Blather::Stanza::Presence::Status.new(:dnd)
|
|
101
|
+
@p3.from = 'n@d/c'
|
|
102
|
+
@p3.priority = 10
|
|
103
|
+
|
|
104
|
+
@i.status = @p
|
|
105
|
+
@i.status = @p2
|
|
106
|
+
@i.status = @p3
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'removes old unavailable presences' do
|
|
110
|
+
setup_item_with_presences
|
|
111
|
+
|
|
112
|
+
50.times do |i|
|
|
113
|
+
p = Blather::Stanza::Presence::Status.new
|
|
114
|
+
p.type = :unavailable
|
|
115
|
+
p.from = "n@d/#{i}"
|
|
116
|
+
@i.status = p
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
@i.statuses.size.should == 4
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'initializes groups to [nil] if the item is not part of a group' do
|
|
123
|
+
i = Blather::RosterItem.new 'n@d'
|
|
124
|
+
i.groups.should == [nil]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'can determine equality' do
|
|
128
|
+
item1 = Blather::RosterItem.new 'n@d'
|
|
129
|
+
item2 = Blather::RosterItem.new 'n@d'
|
|
130
|
+
item1.groups = %w[group1 group2]
|
|
131
|
+
item2.groups = %w[group1 group2]
|
|
132
|
+
(item1 == item2).should == true
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blather::Roster do
|
|
4
|
+
before do
|
|
5
|
+
@stream = mock()
|
|
6
|
+
@stream.stubs(:write)
|
|
7
|
+
|
|
8
|
+
@stanza = mock()
|
|
9
|
+
items = []; 4.times { |n| items << Blather::JID.new("n@d/#{n}r") }
|
|
10
|
+
@stanza.stubs(:items).returns(items)
|
|
11
|
+
|
|
12
|
+
@roster = Blather::Roster.new(@stream, @stanza)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'initializes with items' do
|
|
16
|
+
@roster.items.map { |_,i| i.jid.to_s }.should == (@stanza.items.map { |i| i.stripped.to_s }.uniq)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'processes @stanzas with remove requests' do
|
|
20
|
+
s = @roster['n@d/0r']
|
|
21
|
+
s.subscription = :remove
|
|
22
|
+
proc { @roster.process(s.to_stanza) }.should change(@roster, :length).by -1
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'processes @stanzas with add requests' do
|
|
26
|
+
s = Blather::Stanza::Iq::Roster::RosterItem.new('a@b/c').to_stanza
|
|
27
|
+
proc { @roster.process(s) }.should change(@roster, :length).by 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'allows a jid to be pushed' do
|
|
31
|
+
jid = 'a@b/c'
|
|
32
|
+
proc { @roster.push(jid) }.should change(@roster, :length).by 1
|
|
33
|
+
@roster[jid].should_not be_nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'allows an item to be pushed' do
|
|
37
|
+
jid = 'a@b/c'
|
|
38
|
+
item = Blather::RosterItem.new(Blather::JID.new(jid))
|
|
39
|
+
proc { @roster.push(item) }.should change(@roster, :length).by 1
|
|
40
|
+
@roster[jid].should_not be_nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'aliases #<< to #push and returns self to allow for chaining' do
|
|
44
|
+
jid = 'a@b/c'
|
|
45
|
+
item = Blather::RosterItem.new(Blather::JID.new(jid))
|
|
46
|
+
jid2 = 'd@e/f'
|
|
47
|
+
item2 = Blather::RosterItem.new(Blather::JID.new(jid2))
|
|
48
|
+
proc { @roster << item << item2 }.should change(@roster, :length).by 2
|
|
49
|
+
@roster[jid].should_not be_nil
|
|
50
|
+
@roster[jid2].should_not be_nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'sends a @roster addition over the wire' do
|
|
54
|
+
client = mock(:write => nil)
|
|
55
|
+
roster = Blather::Roster.new client, @stanza
|
|
56
|
+
roster.push('a@b/c')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'removes a Blather::JID' do
|
|
60
|
+
proc { @roster.delete 'n@d' }.should change(@roster, :length).by -1
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'sends a @roster removal over the wire' do
|
|
64
|
+
client = mock(:write => nil)
|
|
65
|
+
roster = Blather::Roster.new client, @stanza
|
|
66
|
+
roster.delete('a@b/c')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'returns an item through []' do
|
|
70
|
+
item = @roster['n@d']
|
|
71
|
+
item.should be_kind_of Blather::RosterItem
|
|
72
|
+
item.jid.should == Blather::JID.new('n@d')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'responds to #each' do
|
|
76
|
+
@roster.should respond_to :each
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'cycles through all the items using #each' do
|
|
80
|
+
@roster.map { |i| i }.sort.should ==(@roster.items.values.sort)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'yields RosterItems from #each' do
|
|
84
|
+
@roster.map { |i| i.should be_kind_of Blather::RosterItem }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'returns a duplicate of items through #items' do
|
|
88
|
+
items = @roster.items
|
|
89
|
+
items.delete 'n@d'
|
|
90
|
+
items.should_not equal @roster.items
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'will group roster items' do
|
|
94
|
+
@roster.delete 'n@d'
|
|
95
|
+
item1 = Blather::RosterItem.new("n1@d")
|
|
96
|
+
item1.groups = ['group1', 'group2']
|
|
97
|
+
item2 = Blather::RosterItem.new("n2@d")
|
|
98
|
+
item2.groups = ['group1', 'group3']
|
|
99
|
+
@roster << item1 << item2
|
|
100
|
+
|
|
101
|
+
@roster.grouped.should ==({
|
|
102
|
+
'group1' => [item1, item2],
|
|
103
|
+
'group2' => [item1],
|
|
104
|
+
'group3' => [item2]
|
|
105
|
+
})
|
|
106
|
+
end
|
|
107
|
+
end
|