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,93 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
def vcard_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<iq type="result" id="blather0007" to="romeo@example.net">
|
|
6
|
+
<vCard xmlns="vcard-temp">
|
|
7
|
+
<NICKNAME>Romeo</NICKNAME>
|
|
8
|
+
</vCard>
|
|
9
|
+
</iq>
|
|
10
|
+
XML
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe Blather::Stanza::Iq::Vcard do
|
|
14
|
+
it 'registers itself' do
|
|
15
|
+
Blather::XMPPNode.class_from_registration(:vCard, 'vcard-temp').should == Blather::Stanza::Iq::Vcard
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'can be imported' do
|
|
19
|
+
query = Blather::XMPPNode.parse vcard_xml
|
|
20
|
+
query.should be_instance_of Blather::Stanza::Iq::Vcard
|
|
21
|
+
query.vcard.should be_instance_of Blather::Stanza::Iq::Vcard::Vcard
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'ensures a vcard node is present on create' do
|
|
25
|
+
query = Blather::Stanza::Iq::Vcard.new
|
|
26
|
+
query.xpath('ns:vCard', :ns => 'vcard-temp').should_not be_empty
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'ensures a vcard node exists when calling #vcard' do
|
|
30
|
+
query = Blather::Stanza::Iq::Vcard.new
|
|
31
|
+
query.vcard.remove
|
|
32
|
+
query.xpath('ns:vCard', :ns => 'vcard-temp').should be_empty
|
|
33
|
+
|
|
34
|
+
query.vcard.should_not be_nil
|
|
35
|
+
query.xpath('ns:vCard', :ns => 'vcard-temp').should_not be_empty
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'ensures a vcard node is replaced when calling #vcard=' do
|
|
39
|
+
query = Blather::XMPPNode.parse vcard_xml
|
|
40
|
+
|
|
41
|
+
new_vcard = Blather::Stanza::Iq::Vcard::Vcard.new
|
|
42
|
+
new_vcard["NICKNAME"] = 'Mercutio'
|
|
43
|
+
|
|
44
|
+
query.vcard = new_vcard
|
|
45
|
+
|
|
46
|
+
query.xpath('ns:vCard', :ns => 'vcard-temp').size.should == 1
|
|
47
|
+
query.find_first('ns:vCard/ns:NICKNAME', :ns => 'vcard-temp').content.should == 'Mercutio'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe Blather::Stanza::Iq::Vcard::Vcard do
|
|
52
|
+
it 'can set vcard elements' do
|
|
53
|
+
query = Blather::Stanza::Iq::Vcard.new :set
|
|
54
|
+
query.vcard['NICKNAME'] = 'Romeo'
|
|
55
|
+
query.find_first('ns:vCard/ns:NICKNAME', :ns => 'vcard-temp').content.should == 'Romeo'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'can set deep vcard elements' do
|
|
59
|
+
query = Blather::Stanza::Iq::Vcard.new :set
|
|
60
|
+
query.vcard['PHOTO/TYPE'] = 'image/png'
|
|
61
|
+
query.vcard['PHOTO/BINVAL'] = '===='
|
|
62
|
+
query.find_first('ns:vCard/ns:PHOTO', :ns => 'vcard-temp').children.size.should == 2
|
|
63
|
+
query.find_first('ns:vCard/ns:PHOTO', :ns => 'vcard-temp').children.detect { |n| n.element_name == 'TYPE' && n.content == 'image/png' }.should_not be_nil
|
|
64
|
+
query.find_first('ns:vCard/ns:PHOTO', :ns => 'vcard-temp').children.detect { |n| n.element_name == 'BINVAL' && n.content == '====' }.should_not be_nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'can get vcard elements' do
|
|
68
|
+
query = Blather::Stanza::Iq::Vcard.new :set
|
|
69
|
+
query.vcard['NICKNAME'] = 'Romeo'
|
|
70
|
+
query.vcard['NICKNAME'].should == 'Romeo'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'can get deep vcard elements' do
|
|
74
|
+
query = Blather::Stanza::Iq::Vcard.new :set
|
|
75
|
+
query.vcard['PHOTO/TYPE'] = 'image/png'
|
|
76
|
+
query.vcard['PHOTO/BINVAL'] = '===='
|
|
77
|
+
query.vcard['PHOTO/TYPE'].should == 'image/png'
|
|
78
|
+
query.vcard['PHOTO/BINVAL'].should == '===='
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'returns nil on vcard elements which does not exist' do
|
|
82
|
+
query = Blather::Stanza::Iq::Vcard.new :set
|
|
83
|
+
query.vcard['NICKNAME'] = 'Romeo'
|
|
84
|
+
query.vcard['FN'].should be_nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'can update vcard elements' do
|
|
88
|
+
query = Blather::XMPPNode.parse vcard_xml
|
|
89
|
+
query.vcard['NICKNAME'].should == 'Romeo'
|
|
90
|
+
query.vcard['NICKNAME'] = 'Mercutio'
|
|
91
|
+
query.vcard['NICKNAME'].should == 'Mercutio'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Iq do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:iq, nil).should == Blather::Stanza::Iq
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'must be importable' do
|
|
9
|
+
string = "<iq from='juliet@example.com/balcony' type='set' id='roster_4'></iq>"
|
|
10
|
+
Blather::XMPPNode.parse(string).should 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.should == :get
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'sets the id when created' do
|
|
18
|
+
Blather::Stanza::Iq.new.id.should_not 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')).should 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).should 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 }.should raise_error(Blather::ArgumentError)
|
|
33
|
+
|
|
34
|
+
Blather::Stanza::Iq::VALID_TYPES.each do |valid_type|
|
|
35
|
+
n = Blather::Stanza::Iq.new valid_type
|
|
36
|
+
n.type.should == 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.should respond_to :"#{valid_type}?"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'removes the body when replying' do
|
|
47
|
+
iq = Blather::Stanza::Iq.new :get, 'me@example.com'
|
|
48
|
+
iq.from = 'them@example.com'
|
|
49
|
+
iq << Blather::XMPPNode.new('query', iq.document)
|
|
50
|
+
r = iq.reply
|
|
51
|
+
r.children.empty?.should == true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'does not remove the body when replying if we ask to keep it' do
|
|
55
|
+
iq = Blather::Stanza::Iq.new :get, 'me@example.com'
|
|
56
|
+
iq.from = 'them@example.com'
|
|
57
|
+
iq << Blather::XMPPNode.new('query', iq.document)
|
|
58
|
+
r = iq.reply :remove_children => false
|
|
59
|
+
r.children.empty?.should == false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
def muc_invite_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<message
|
|
6
|
+
from='coven@chat.shakespeare.lit'
|
|
7
|
+
id='nzd143v8'
|
|
8
|
+
to='hecate@shakespeare.lit'>
|
|
9
|
+
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
10
|
+
<invite to='hecate@shakespeare.lit' from='crone1@shakespeare.lit/desktop'>
|
|
11
|
+
<reason>
|
|
12
|
+
Hey Hecate, this is the place for all good witches!
|
|
13
|
+
</reason>
|
|
14
|
+
</invite>
|
|
15
|
+
<password>foobar</password>
|
|
16
|
+
</x>
|
|
17
|
+
</message>
|
|
18
|
+
XML
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def muc_decline_xml
|
|
22
|
+
<<-XML
|
|
23
|
+
<message
|
|
24
|
+
from='hecate@shakespeare.lit/broom'
|
|
25
|
+
id='jk2vs61v'
|
|
26
|
+
to='coven@chat.shakespeare.lit'>
|
|
27
|
+
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
28
|
+
<decline to='crone1@shakespeare.lit' from='hecate@shakespeare.lit'>
|
|
29
|
+
<reason>
|
|
30
|
+
Sorry, I'm too busy right now.
|
|
31
|
+
</reason>
|
|
32
|
+
</decline>
|
|
33
|
+
</x>
|
|
34
|
+
</message>
|
|
35
|
+
XML
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe 'Blather::Stanza::Message::MUCUser' do
|
|
39
|
+
it 'ensures a form node is present on create' do
|
|
40
|
+
c = Blather::Stanza::Message::MUCUser.new
|
|
41
|
+
c.xpath('ns:x', :ns => Blather::Stanza::Message::MUCUser.registered_ns).should_not be_empty
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'ensures a form node exists when calling #muc' do
|
|
45
|
+
c = Blather::Stanza::Message::MUCUser.new
|
|
46
|
+
c.remove_children :x
|
|
47
|
+
c.xpath('ns:x', :ns => Blather::Stanza::Message::MUCUser.registered_ns).should be_empty
|
|
48
|
+
|
|
49
|
+
c.muc_user.should_not be_nil
|
|
50
|
+
c.xpath('ns:x', :ns => Blather::Stanza::Message::MUCUser.registered_ns).should_not be_empty
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'ensures the message type is :normal' do
|
|
54
|
+
m = Blather::Stanza::Message::MUCUser.new
|
|
55
|
+
m.normal?.should == true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "must be able to set the password" do
|
|
59
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
60
|
+
muc_user.password.should == nil
|
|
61
|
+
muc_user.password = 'barbaz'
|
|
62
|
+
muc_user.password.should == 'barbaz'
|
|
63
|
+
muc_user.password = 'hello_world'
|
|
64
|
+
muc_user.password.should == 'hello_world'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should not be an #invite?" do
|
|
68
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
69
|
+
muc_user.invite?.should == false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "with an invite element" do
|
|
73
|
+
it "should be an #invite?" do
|
|
74
|
+
muc_user = Blather::XMPPNode.parse(muc_invite_xml)
|
|
75
|
+
muc_user.invite?.should == true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should know the invite attributes properly" do
|
|
79
|
+
muc_user = Blather::XMPPNode.parse(muc_invite_xml)
|
|
80
|
+
muc_user.should be_instance_of Blather::Stanza::Message::MUCUser
|
|
81
|
+
invite = muc_user.invite
|
|
82
|
+
invite.to.should == 'hecate@shakespeare.lit'
|
|
83
|
+
invite.from.should == 'crone1@shakespeare.lit/desktop'
|
|
84
|
+
invite.reason.should == 'Hey Hecate, this is the place for all good witches!'
|
|
85
|
+
muc_user.password.should == 'foobar'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "must be able to set the to jid" do
|
|
89
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
90
|
+
invite = muc_user.invite
|
|
91
|
+
invite.to.should == nil
|
|
92
|
+
invite.to = 'foo@bar.com'
|
|
93
|
+
invite.to.should == 'foo@bar.com'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "must be able to set the from jid" do
|
|
97
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
98
|
+
invite = muc_user.invite
|
|
99
|
+
invite.from.should == nil
|
|
100
|
+
invite.from = 'foo@bar.com'
|
|
101
|
+
invite.from.should == 'foo@bar.com'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "must be able to set the reason" do
|
|
105
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
106
|
+
invite = muc_user.invite
|
|
107
|
+
invite.reason.should == ''
|
|
108
|
+
invite.reason = 'Please join'
|
|
109
|
+
invite.reason.should == 'Please join'
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "with a decline element" do
|
|
114
|
+
it "should be an #invite_decline?" do
|
|
115
|
+
muc_user = Blather::XMPPNode.parse(muc_decline_xml)
|
|
116
|
+
muc_user.should be_instance_of Blather::Stanza::Message::MUCUser
|
|
117
|
+
muc_user.invite_decline?.should == true
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should know the decline attributes properly" do
|
|
121
|
+
muc_user = Blather::XMPPNode.parse(muc_decline_xml)
|
|
122
|
+
decline = muc_user.decline
|
|
123
|
+
decline.to.should == 'crone1@shakespeare.lit'
|
|
124
|
+
decline.from.should == 'hecate@shakespeare.lit'
|
|
125
|
+
decline.reason.should == "Sorry, I'm too busy right now."
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "must be able to set the to jid" do
|
|
129
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
130
|
+
decline = muc_user.decline
|
|
131
|
+
decline.to.should == nil
|
|
132
|
+
decline.to = 'foo@bar.com'
|
|
133
|
+
decline.to.should == 'foo@bar.com'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "must be able to set the from jid" do
|
|
137
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
138
|
+
decline = muc_user.decline
|
|
139
|
+
decline.from.should == nil
|
|
140
|
+
decline.from = 'foo@bar.com'
|
|
141
|
+
decline.from.should == 'foo@bar.com'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "must be able to set the reason" do
|
|
145
|
+
muc_user = Blather::Stanza::Message::MUCUser.new
|
|
146
|
+
decline = muc_user.decline
|
|
147
|
+
decline.reason.should == ''
|
|
148
|
+
decline.reason = 'Please join'
|
|
149
|
+
decline.reason.should == 'Please join'
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
def ichat_message_xml
|
|
4
|
+
<<-XML
|
|
5
|
+
<message from="juliet@example.com/balcony" to="romeo@example.net" type="chat" id="iChat_5FA6C6DC">
|
|
6
|
+
<body>Hello</body>
|
|
7
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
8
|
+
<body style="background-color:#7bb5ee;color:#000000;">
|
|
9
|
+
<span style="font-family: 'Arial';font-size: 12px;color: #262626;">Hello</span>
|
|
10
|
+
<img alt="f5ad3a04d218d7160fa02415e02d41b3.jpg" src="message-attachments:1" width="30" height="30"/>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
13
|
+
|
|
14
|
+
<x xmlns="http://www.apple.com/xmpp/message-attachments">
|
|
15
|
+
<attachment id="1">
|
|
16
|
+
<sipub xmlns="http://jabber.org/protocol/sipub" from="juliet@example.com/balcony" id="sipubid_77933F62" mime-type="binary/octet-stream" profile="http://jabber.org/protocol/si/profile/file-transfer">
|
|
17
|
+
<file xmlns="http://jabber.org/protocol/si/profile/file-transfer" xmlns:ichat="apple:profile:transfer-extensions" name="f5ad3a04d218d7160fa02415e02d41b3.jpg" size="1245" posixflags="000001A4"/>
|
|
18
|
+
</sipub>
|
|
19
|
+
</attachment>
|
|
20
|
+
</x>
|
|
21
|
+
|
|
22
|
+
<iq type="set" id="iChat_4CC32F1F" to="romeo@example.net">
|
|
23
|
+
<si xmlns="http://jabber.org/protocol/si" id="sid_60C2D273" mime-type="binary/octet-stream" profile="http://jabber.org/protocol/si/profile/file-transfer">
|
|
24
|
+
<file xmlns="http://jabber.org/protocol/si/profile/file-transfer" xmlns:ichat="apple:profile:transfer-extensions" name="f5ad3a04d218d7160fa02415e02d41b3.jpg" size="1245" posixflags="000001A4"/>
|
|
25
|
+
<feature xmlns="http://jabber.org/protocol/feature-neg">
|
|
26
|
+
<x xmlns="jabber:x:data" type="form">
|
|
27
|
+
<field type="list-single" var="stream-method">
|
|
28
|
+
<option><value>http://jabber.org/protocol/bytestreams</value></option>
|
|
29
|
+
</field>
|
|
30
|
+
</x>
|
|
31
|
+
</feature>
|
|
32
|
+
</si>
|
|
33
|
+
</iq>
|
|
34
|
+
</message>
|
|
35
|
+
XML
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def message_xml
|
|
39
|
+
<<-XML
|
|
40
|
+
<message
|
|
41
|
+
to='romeo@example.net'
|
|
42
|
+
from='juliet@example.com/balcony'
|
|
43
|
+
type='chat'
|
|
44
|
+
xml:lang='en'>
|
|
45
|
+
<body>Wherefore art thou, Romeo?</body>
|
|
46
|
+
<x xmlns='jabber:x:data' type='form'>
|
|
47
|
+
<field var='field-name' type='text-single' label='description' />
|
|
48
|
+
</x>
|
|
49
|
+
<paused xmlns="http://jabber.org/protocol/chatstates"/>
|
|
50
|
+
</message>
|
|
51
|
+
XML
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def delayed_message_xml
|
|
55
|
+
<<-XML
|
|
56
|
+
<message
|
|
57
|
+
from='coven@chat.shakespeare.lit/firstwitch'
|
|
58
|
+
id='162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2'
|
|
59
|
+
to='hecate@shakespeare.lit/broom'
|
|
60
|
+
type='groupchat'>
|
|
61
|
+
<body>Thrice the brinded cat hath mew'd.</body>
|
|
62
|
+
<delay xmlns='urn:xmpp:delay'
|
|
63
|
+
from='coven@chat.shakespeare.lit'
|
|
64
|
+
stamp='2002-10-13T23:58:37Z'>
|
|
65
|
+
Too slow
|
|
66
|
+
</delay>
|
|
67
|
+
</message>
|
|
68
|
+
XML
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe Blather::Stanza::Message do
|
|
72
|
+
it 'registers itself' do
|
|
73
|
+
Blather::XMPPNode.class_from_registration(:message, nil).should == Blather::Stanza::Message
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'must be importable' do
|
|
77
|
+
Blather::XMPPNode.parse(message_xml).should be_instance_of Blather::Stanza::Message
|
|
78
|
+
Blather::XMPPNode.parse(ichat_message_xml).should be_instance_of Blather::Stanza::Message
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'provides "attr_accessor" for body' do
|
|
82
|
+
s = Blather::Stanza::Message.new
|
|
83
|
+
s.body.should be_nil
|
|
84
|
+
s.find('body').should be_empty
|
|
85
|
+
|
|
86
|
+
s.body = 'test message'
|
|
87
|
+
s.body.should_not be_nil
|
|
88
|
+
s.find('body').should_not be_empty
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'provides "attr_accessor" for subject' do
|
|
92
|
+
s = Blather::Stanza::Message.new
|
|
93
|
+
s.subject.should be_nil
|
|
94
|
+
s.find('subject').should be_empty
|
|
95
|
+
|
|
96
|
+
s.subject = 'test subject'
|
|
97
|
+
s.subject.should_not be_nil
|
|
98
|
+
s.find('subject').should_not be_empty
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'provides "attr_accessor" for thread' do
|
|
102
|
+
s = Blather::Stanza::Message.new
|
|
103
|
+
s.thread.should be_nil
|
|
104
|
+
s.find('thread').should be_empty
|
|
105
|
+
|
|
106
|
+
s.thread = 1234
|
|
107
|
+
s.thread.should_not be_nil
|
|
108
|
+
s.find('thread').should_not be_empty
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'can set a parent attribute for thread' do
|
|
112
|
+
s = Blather::Stanza::Message.new
|
|
113
|
+
s.thread.should be_nil
|
|
114
|
+
s.find('thread').should be_empty
|
|
115
|
+
|
|
116
|
+
s.thread = {4321 => 1234}
|
|
117
|
+
s.thread.should == '1234'
|
|
118
|
+
s.parent_thread.should == '4321'
|
|
119
|
+
s.find('thread[@parent="4321"]').should_not be_empty
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'ensures type is one of Blather::Stanza::Message::VALID_TYPES' do
|
|
123
|
+
lambda { Blather::Stanza::Message.new nil, nil, :invalid_type_name }.should raise_error(Blather::ArgumentError)
|
|
124
|
+
|
|
125
|
+
Blather::Stanza::Message::VALID_TYPES.each do |valid_type|
|
|
126
|
+
msg = Blather::Stanza::Message.new nil, nil, valid_type
|
|
127
|
+
msg.type.should == valid_type
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
Blather::Stanza::Message::VALID_TYPES.each do |valid_type|
|
|
132
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
|
133
|
+
Blather::Stanza::Message.new.should respond_to :"#{valid_type}?"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'ensures an html node exists when asked for xhtml_node' do
|
|
138
|
+
search_args = [
|
|
139
|
+
'/message/html_ns:html',
|
|
140
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS}
|
|
141
|
+
]
|
|
142
|
+
msg = Blather::Stanza::Message.new
|
|
143
|
+
msg.find_first(*search_args).should be_nil
|
|
144
|
+
|
|
145
|
+
msg.xhtml_node
|
|
146
|
+
msg.find_first(*search_args).should_not be_nil
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'ensures a body node exists when asked for xhtml_node' do
|
|
150
|
+
search_args = [
|
|
151
|
+
'/message/html_ns:html/body_ns:body',
|
|
152
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS,
|
|
153
|
+
:body_ns => Blather::Stanza::Message::HTML_BODY_NS}
|
|
154
|
+
]
|
|
155
|
+
msg = Blather::Stanza::Message.new
|
|
156
|
+
msg.find_first(*search_args).should be_nil
|
|
157
|
+
|
|
158
|
+
msg.xhtml_node
|
|
159
|
+
msg.find_first(*search_args).should_not be_nil
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'returns an existing node when asked for xhtml_node' do
|
|
163
|
+
msg = Blather::Stanza::Message.new
|
|
164
|
+
msg << (h = Blather::XMPPNode.new('html', msg.document))
|
|
165
|
+
h.namespace = Blather::Stanza::Message::HTML_NS
|
|
166
|
+
b = Blather::XMPPNode.new('body', msg.document)
|
|
167
|
+
b.namespace = Blather::Stanza::Message::HTML_BODY_NS
|
|
168
|
+
h << b
|
|
169
|
+
|
|
170
|
+
msg.xhtml_node.should ==(b)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it 'has an xhtml setter' do
|
|
174
|
+
msg = Blather::Stanza::Message.new
|
|
175
|
+
xhtml = "<some>xhtml</some>"
|
|
176
|
+
msg.xhtml = xhtml
|
|
177
|
+
msg.xhtml_node.inner_html.strip.should ==(xhtml)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'sets valid xhtml even if the input is not valid' do
|
|
181
|
+
msg = Blather::Stanza::Message.new
|
|
182
|
+
xhtml = "<some>xhtml"
|
|
183
|
+
msg.xhtml = xhtml
|
|
184
|
+
msg.xhtml_node.inner_html.strip.should ==("<some>xhtml</some>")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'sets xhtml with more than one root node' do
|
|
188
|
+
msg = Blather::Stanza::Message.new
|
|
189
|
+
xhtml = "<i>xhtml</i> more xhtml"
|
|
190
|
+
msg.xhtml = xhtml
|
|
191
|
+
msg.xhtml_node.inner_html.strip.should ==("<i>xhtml</i> more xhtml")
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'has an xhtml getter' do
|
|
195
|
+
msg = Blather::Stanza::Message.new
|
|
196
|
+
xhtml = "<some>xhtml</some>"
|
|
197
|
+
msg.xhtml = xhtml
|
|
198
|
+
msg.xhtml.should ==(xhtml)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'finds xhtml body when html wrapper has wrong namespace' do
|
|
202
|
+
msg = Blather::XMPPNode.parse(ichat_message_xml)
|
|
203
|
+
msg.xhtml.should == "<span style=\"font-family: 'Arial';font-size: 12px;color: #262626;\">Hello</span>\n <img alt=\"f5ad3a04d218d7160fa02415e02d41b3.jpg\" src=\"message-attachments:1\" width=\"30\" height=\"30\"></img>"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'has a chat state setter' do
|
|
207
|
+
msg = Blather::Stanza::Message.new
|
|
208
|
+
msg.chat_state = :composing
|
|
209
|
+
msg.xpath('ns:composing', :ns => Blather::Stanza::Message::CHAT_STATE_NS).should_not be_empty
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'will only add one chat state at a time' do
|
|
213
|
+
msg = Blather::Stanza::Message.new
|
|
214
|
+
msg.chat_state = :composing
|
|
215
|
+
msg.chat_state = :paused
|
|
216
|
+
|
|
217
|
+
msg.xpath('ns:*', :ns => Blather::Stanza::Message::CHAT_STATE_NS).size.should ==(1)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'ensures chat state setter accepts strings' do
|
|
221
|
+
msg = Blather::Stanza::Message.new
|
|
222
|
+
msg.chat_state = "gone"
|
|
223
|
+
msg.xpath('ns:gone', :ns => Blather::Stanza::Message::CHAT_STATE_NS).should_not be_empty
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it 'ensures chat state is one of Blather::Stanza::Message::VALID_CHAT_STATES' do
|
|
227
|
+
lambda do
|
|
228
|
+
msg = Blather::Stanza::Message.new
|
|
229
|
+
msg.chat_state = :invalid_chat_state
|
|
230
|
+
end.should raise_error(Blather::ArgumentError)
|
|
231
|
+
|
|
232
|
+
Blather::Stanza::Message::VALID_CHAT_STATES.each do |valid_chat_state|
|
|
233
|
+
msg = Blather::Stanza::Message.new
|
|
234
|
+
msg.chat_state = valid_chat_state
|
|
235
|
+
msg.chat_state.should == valid_chat_state
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'has a chat state getter' do
|
|
240
|
+
msg = Blather::Stanza::Message.new
|
|
241
|
+
msg.chat_state = :paused
|
|
242
|
+
msg.chat_state.should ==(:paused)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it 'imports correct chat state' do
|
|
246
|
+
Blather::XMPPNode.parse(message_xml).chat_state.should == :paused
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'makes a form child available' do
|
|
250
|
+
n = Blather::XMPPNode.parse(message_xml)
|
|
251
|
+
n.form.fields.size.should == 1
|
|
252
|
+
n.form.fields.map { |f| f.class }.uniq.should == [Blather::Stanza::X::Field]
|
|
253
|
+
n.form.should be_instance_of Blather::Stanza::X
|
|
254
|
+
|
|
255
|
+
r = Blather::Stanza::Message.new
|
|
256
|
+
r.form.type = :form
|
|
257
|
+
r.form.type.should == :form
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it 'ensures the form child is a direct child' do
|
|
261
|
+
r = Blather::Stanza::Message.new
|
|
262
|
+
r.form
|
|
263
|
+
r.xpath('ns:x', :ns => Blather::Stanza::X.registered_ns).should_not be_empty
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'is not delayed' do
|
|
267
|
+
n = Blather::XMPPNode.parse(message_xml)
|
|
268
|
+
n.delay.should == nil
|
|
269
|
+
n.delayed?.should == false
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
describe "with a delay" do
|
|
273
|
+
it "is delayed" do
|
|
274
|
+
n = Blather::XMPPNode.parse(delayed_message_xml)
|
|
275
|
+
n.delayed?.should == true
|
|
276
|
+
n.delay.should be_instance_of Blather::Stanza::Message::Delay
|
|
277
|
+
n.delay.from.should == 'coven@chat.shakespeare.lit'
|
|
278
|
+
n.delay.stamp.should == Time.utc(2002, 10, 13, 23, 58, 37, 0)
|
|
279
|
+
n.delay.description.should == "Too slow"
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|