tp-blather 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blather::Stream::Component do
|
4
|
+
class MockServer; end
|
5
|
+
module ServerMock
|
6
|
+
def receive_data(data)
|
7
|
+
@server ||= MockServer.new
|
8
|
+
@server.receive_data data, self
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def mocked_server(times = nil, &block)
|
13
|
+
@client ||= mock()
|
14
|
+
@client.stubs(:unbind) unless @client.respond_to?(:unbind)
|
15
|
+
@client.stubs(:jid=) unless @client.respond_to?(:jid=)
|
16
|
+
|
17
|
+
port = 50000 - rand(1000)
|
18
|
+
|
19
|
+
MockServer.any_instance.expects(:receive_data).send(*(times ? [:times, times] : [:at_least, 1])).with &block
|
20
|
+
EventMachine::run {
|
21
|
+
# Mocked server
|
22
|
+
EventMachine::start_server '127.0.0.1', port, ServerMock
|
23
|
+
|
24
|
+
# Blather::Stream connection
|
25
|
+
EM.connect('127.0.0.1', port, Blather::Stream::Component, @client, @jid || 'comp.id', 'secret') { |c| @stream = c }
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'can be started' do
|
30
|
+
client = mock()
|
31
|
+
params = [client, 'comp.id', 'secret', 'host', 1234]
|
32
|
+
EM.expects(:connect).with do |*parms|
|
33
|
+
parms[0] == 'host' &&
|
34
|
+
parms[1] == 1234 &&
|
35
|
+
parms[3] == client &&
|
36
|
+
parms[4] == 'comp.id'
|
37
|
+
end
|
38
|
+
|
39
|
+
Blather::Stream::Component.start *params
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'shakes hands with the server' do
|
43
|
+
state = nil
|
44
|
+
mocked_server(2) do |val, server|
|
45
|
+
case state
|
46
|
+
when nil
|
47
|
+
state = :started
|
48
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' id='12345'>"
|
49
|
+
val.should match(/stream:stream/)
|
50
|
+
|
51
|
+
when :started
|
52
|
+
server.send_data '<handshake/>'
|
53
|
+
EM.stop
|
54
|
+
val.should == "<handshake>#{Digest::SHA1.hexdigest('12345'+"secret")}</handshake>"
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'raises a NoConnection exception if the connection is unbound before it can be completed' do
|
61
|
+
@client = mock
|
62
|
+
proc do
|
63
|
+
EventMachine::run {
|
64
|
+
EM.add_timer(0.5) { EM.stop if EM.reactor_running? }
|
65
|
+
|
66
|
+
Blather::Stream::Component.start @client, @jid || Blather::JID.new('n@d/r'), 'pass', '127.0.0.1', 50000 - rand(1000)
|
67
|
+
}
|
68
|
+
end.should raise_error Blather::Stream::ConnectionFailed
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'starts the stream once the connection is complete' do
|
72
|
+
mocked_server(1) { |val, _| EM.stop; val.should match(/stream:stream/) }
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'sends stanzas to the client when the stream is ready' do
|
76
|
+
@client = mock(:post_init)
|
77
|
+
@client.expects(:receive_data).with do |n|
|
78
|
+
EM.stop
|
79
|
+
n.kind_of? Blather::XMPPNode
|
80
|
+
end
|
81
|
+
|
82
|
+
state = nil
|
83
|
+
mocked_server(2) do |val, server|
|
84
|
+
case state
|
85
|
+
when nil
|
86
|
+
state = :started
|
87
|
+
server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' id='12345'>"
|
88
|
+
val.should match(/stream:stream/)
|
89
|
+
|
90
|
+
when :started
|
91
|
+
server.send_data '<handshake/>'
|
92
|
+
server.send_data "<message to='comp.id' from='d@e/f' type='chat' xml:lang='en'><body>Message!</body></message>"
|
93
|
+
val.should == "<handshake>#{Digest::SHA1.hexdigest('12345'+"secret")}</handshake>"
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'sends stanzas to the wire ensuring "from" is set' do
|
100
|
+
client = mock()
|
101
|
+
client.stubs(:jid)
|
102
|
+
client.stubs(:jid=)
|
103
|
+
msg = Blather::Stanza::Message.new 'to@jid.com', 'body'
|
104
|
+
comp = Blather::Stream::Component.new nil, client, 'jid.com', 'pass'
|
105
|
+
comp.expects(:send_data).with { |s| s.should match(/^<message[^>]*from="jid\.com"/) }
|
106
|
+
comp.send msg
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blather::Stream::Parser do
|
4
|
+
let :client do
|
5
|
+
Class.new do
|
6
|
+
attr_reader :data
|
7
|
+
attr_accessor :latch
|
8
|
+
def stopped?; false; end
|
9
|
+
def receive(node)
|
10
|
+
@data ||= []
|
11
|
+
@data << node
|
12
|
+
latch.countdown!
|
13
|
+
end
|
14
|
+
end.new
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { Blather::Stream::Parser.new client }
|
18
|
+
|
19
|
+
def process(*data)
|
20
|
+
client.latch = CountDownLatch.new 1
|
21
|
+
data.each { |d| subject.receive_data d }
|
22
|
+
client.latch.wait(2).should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_parse(data)
|
26
|
+
process data
|
27
|
+
client.data.size.should == 1
|
28
|
+
client.data[0].to_s.gsub(/\n\s*/,'').should == data
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'handles fragmented parsing' do
|
32
|
+
process '<foo>', '<bar/>', '</foo>'
|
33
|
+
client.data.size.should == 1
|
34
|
+
client.data[0].to_s.gsub(/\n\s*/,'').should == '<foo><bar/></foo>'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'handles a basic example' do
|
38
|
+
check_parse "<foo/>"
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'handles a basic namespace definition' do
|
42
|
+
check_parse '<foo xmlns="bar:baz"/>'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'handles multiple namespace definitions' do
|
46
|
+
check_parse '<foo xmlns="bar:baz" xmlns:bar="baz"/>'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'handles prefix namespacing' do
|
50
|
+
check_parse '<bar:foo xmlns="bar:baz" xmlns:bar="baz"/>'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'handles namespaces with children' do
|
54
|
+
check_parse "<foo xmlns=\"bar:baz\"><bar/></foo>"
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'handles multiple namespaces with children' do
|
58
|
+
check_parse "<foo xmlns=\"bar:baz\" xmlns:bar=\"baz\"><bar/></foo>"
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'handles prefix namespaces with children' do
|
62
|
+
check_parse "<bar:foo xmlns=\"bar:baz\" xmlns:bar=\"baz\"><bar/></bar:foo>"
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'handles prefix namespaces with children in the namespace' do
|
66
|
+
check_parse "<bar:foo xmlns=\"bar:baz\" xmlns:bar=\"baz\"><bar:bar/></bar:foo>"
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'handles prefix namespaces with children in the namespace' do
|
70
|
+
check_parse "<bar:foo xmlns=\"bar:baz\" xmlns:bar=\"baz\"><baz><bar:buz/></baz></bar:foo>"
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'handles attributes' do
|
74
|
+
check_parse '<foo bar="baz"/>'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'handles attributes with entities properly' do
|
78
|
+
check_parse '<a href="http://example.com?a=1&b=2">example</a>'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'handles character input' do
|
82
|
+
check_parse '<foo>bar baz fizbuz</foo>'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'handles a complex input' do
|
86
|
+
data = [
|
87
|
+
'<message type="error" id="another-id">',
|
88
|
+
'<error type="modify">',
|
89
|
+
'<undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>',
|
90
|
+
'<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Some special application diagnostic information...</text>',
|
91
|
+
'<special-application-condition xmlns="special:application-ns"/>',
|
92
|
+
"</error>",
|
93
|
+
"</message>"
|
94
|
+
]
|
95
|
+
process *data
|
96
|
+
client.data.size.should == 1
|
97
|
+
Nokogiri::XML(client.data[0].to_s.gsub(/\n\s*/, '')).to_s.should == Nokogiri::XML(data.join).to_s
|
98
|
+
client.data[0].xpath('//*[namespace-uri()="urn:ietf:params:xml:ns:xmpp-stanzas"]').size.should == 2
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'handles not absolute namespaces' do
|
102
|
+
lambda do
|
103
|
+
process '<iq type="result" id="blather0007" to="n@d/r"><vCard xmlns="vcard-temp"/></iq>'
|
104
|
+
end.should_not raise_error
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'responds with stream:stream as a separate response' do
|
108
|
+
process '<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
109
|
+
'<foo/>'
|
110
|
+
client.data.size.should == 2
|
111
|
+
client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
112
|
+
client.data[1].to_s.should == '<foo/>'
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'response with stream:end when receiving </stream:stream>' do
|
116
|
+
process '<stream:stream xmlns:stream="http://etherx.jabber.org/streams"/>'
|
117
|
+
client.data.size.should == 2
|
118
|
+
client.data[1].to_s.should == '<stream:end xmlns:stream="http://etherx.jabber.org/streams"/>'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'raises ParseError when an error is sent' do
|
122
|
+
lambda { process "<stream:stream>" }.should raise_error(Blather::ParseError)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'handles stream stanzas without an issue' do
|
126
|
+
process '<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" to="example.com" version="1.0">',
|
127
|
+
'<stream:features/>'
|
128
|
+
client.data.size.should == 2
|
129
|
+
client.data[0].document.xpath('/stream:stream[@to="example.com" and @version="1.0"]', 'xmlns' => 'jabber:client', 'stream' => 'http://etherx.jabber.org/streams').size.should == 1
|
130
|
+
client.data[1].to_s.should == '<stream:features xmlns:stream="http://etherx.jabber.org/streams"/>'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'ignores the client namespace on stanzas' do
|
134
|
+
process "<message type='chat' to='n@d' from='n@d/r' id='id1' xmlns='jabber:client'>",
|
135
|
+
"<body>exit</body>",
|
136
|
+
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>exit</body></html>",
|
137
|
+
"</message>"
|
138
|
+
client.data.size.should == 1
|
139
|
+
client.data[0].document.xpath('/message/body[.="exit"]').should_not be_empty
|
140
|
+
client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'ignores the component namespace on stanzas' do
|
144
|
+
process "<message type='chat' to='n@d' from='n@d/r' id='id1' xmlns='jabber:component:accept'>",
|
145
|
+
"<body>exit</body>",
|
146
|
+
"<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>exit</body></html>",
|
147
|
+
"</message>"
|
148
|
+
client.data.size.should == 1
|
149
|
+
client.data[0].document.xpath('/message/body[.="exit"]').should_not be_empty
|
150
|
+
client.data[0].document.xpath('/message/im:html/xhtml:body[.="exit"]', 'im' => 'http://jabber.org/protocol/xhtml-im', 'xhtml' => 'http://www.w3.org/1999/xhtml').should_not be_empty
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blather::CertStore do
|
4
|
+
before do
|
5
|
+
@pem = "-----BEGIN CERTIFICATE-----\nMIIDszCCApugAwIBAgIETiZC5TANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV\nUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEaMBgGA1UECgwR\nVmluZXMgWE1QUCBTZXJ2ZXIxFDASBgNVBAMMC3ZpbmVzLmxvY2FsMB4XDTExMDcx\nOTAyNTIyMVoXDTEyMDcxOTAyNTIyMVowYzELMAkGA1UEBhMCVVMxETAPBgNVBAgM\nCENvbG9yYWRvMQ8wDQYDVQQHDAZEZW52ZXIxGjAYBgNVBAoMEVZpbmVzIFhNUFAg\nU2VydmVyMRQwEgYDVQQDDAt2aW5lcy5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAMyqj4UyXIpLYyIDaqDoN/8yZHDv281lz1UzuhPZ5r4S6teA\n90dXT6MxEoQ5vpRV2lVU21mDOoRPk9qjgGA01zimrX/YvPf2BBedFkvU18ZKiOMD\n7D89Ej2oIPLc6dJMiIx1SbfpdvUtVZFn1/jGvQPv5iajHW5n/zn1KrHOvVa6R5eY\nVGEH3DD3RkzSxWHyiNN8R5SQzyOVX9F4DVFAffPOLbkFsCi2POy3dp+ZWuYKEjBd\nMuRibrt87PCESnyXZx/Y+GBG856wQT8Ny6mmnh5z5YtopvAJh16ps2p6DFgyDtF+\nhaW3WMlStXYQPqSTrreD7qdAxi3rVft2OUJLTJkCAwEAAaNvMG0wDAYDVR0TBAUw\nAwEB/zAdBgNVHQ4EFgQUUCSlixByIPK3s20w4xHhcMax7igwPgYDVR0RBDcwNYIL\ndmluZXMubG9jYWyCJmNocmlzdG9waGVyLWpvaG5zb25zLW1hY2Jvb2stcHJvLmxv\nY2FsMA0GCSqGSIb3DQEBBQUAA4IBAQBOy1nI7H8XpnpVzpRK5RN/MzelQUl1Efo0\nl9wZ73E6EgJinl2AUp1/sYMUWkVlZ4DSflRBxBEp0CAJNoUydBh8O1xEKGTyqlLy\n/daqvNFLnYwFluAWi1xJQZv4AE62ua5wjsrhPuu3aMvPt9hx1X3CVh+8aA24/gAo\nAPJYsfT3T8GCD+MU3Uc2yADnLSUJ6Jal56/okOJA2Pfkr/K4zj1CyfAEWlpgo2Pv\nyrpv4V2WP1SL5fOONNGfOzio1LD6seAl+8SjiCefnMan2aXmna6SpMDzXB8vTDUE\nWmsD9g0621WqNz2x6lY5IYr7azE2C46Tpb9FOeSAAd83Zka4acaL\n-----END CERTIFICATE-----\n"
|
6
|
+
@cert = File.open("./test.crt", 'w') {|f| f.write(@pem) }
|
7
|
+
@store = Blather::CertStore.new("./")
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
File.delete("./test.crt")
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'can verify valid cert' do
|
15
|
+
@store.trusted?(@pem).tap do |trusted|
|
16
|
+
trusted.should == true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can verify invalid cert' do
|
21
|
+
@store.trusted?(@pem.gsub("L", "a")).tap do |trusted|
|
22
|
+
trusted.should == nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can verify without a cert store' do
|
27
|
+
@store = Blather::CertStore.new("../")
|
28
|
+
@store.trusted?(@pem).tap do |trusted|
|
29
|
+
trusted.should == true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blather::XMPPNode do
|
4
|
+
before { @doc = Nokogiri::XML::Document.new }
|
5
|
+
|
6
|
+
it 'generates a node based on the registered_name' do
|
7
|
+
foo = Class.new(Blather::XMPPNode)
|
8
|
+
foo.registered_name = 'foo'
|
9
|
+
foo.new.element_name.should == 'foo'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'sets the namespace on creation' do
|
13
|
+
foo = Class.new(Blather::XMPPNode)
|
14
|
+
foo.registered_ns = 'foo'
|
15
|
+
foo.new('foo').namespace.href.should == 'foo'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'registers sub classes' do
|
19
|
+
class RegistersSubClass < Blather::XMPPNode; register 'foo', 'foo:bar'; end
|
20
|
+
RegistersSubClass.registered_name.should == 'foo'
|
21
|
+
RegistersSubClass.registered_ns.should == 'foo:bar'
|
22
|
+
Blather::XMPPNode.class_from_registration('foo', 'foo:bar').should == RegistersSubClass
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'imports another node' do
|
26
|
+
class ImportSubClass < Blather::XMPPNode; register 'foo', 'foo:bar'; end
|
27
|
+
n = Blather::XMPPNode.new('foo')
|
28
|
+
n.namespace = 'foo:bar'
|
29
|
+
Blather::XMPPNode.import(n).should be_kind_of ImportSubClass
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can convert itself into a stanza' do
|
33
|
+
class StanzaConvert < Blather::XMPPNode; register 'foo'; end
|
34
|
+
n = Blather::XMPPNode.new('foo')
|
35
|
+
n.to_stanza.should be_kind_of StanzaConvert
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can parse a string and import it' do
|
39
|
+
class StanzaParse < Blather::XMPPNode; register 'foo'; end
|
40
|
+
string = '<foo/>'
|
41
|
+
n = Nokogiri::XML(string).root
|
42
|
+
i = Blather::XMPPNode.import n
|
43
|
+
i.should be_kind_of StanzaParse
|
44
|
+
p = Blather::XMPPNode.parse string
|
45
|
+
p.should be_kind_of StanzaParse
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blather do
|
4
|
+
|
5
|
+
describe "while accessing to Logger object" do
|
6
|
+
it "should return a Logger instance" do
|
7
|
+
Blather.logger.should be_instance_of Logger
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should config log level to info by default" do
|
11
|
+
Blather.logger.level.should == 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "while using the log method" do
|
16
|
+
after do
|
17
|
+
Blather.default_log_level = :debug
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should forward to debug by default" do
|
21
|
+
Blather.logger.expects(:debug).with("foo bar").once
|
22
|
+
Blather.log "foo bar"
|
23
|
+
end
|
24
|
+
|
25
|
+
%w<debug info error fatal>.each do |val|
|
26
|
+
it "should forward to #{val} if configured that default level" do
|
27
|
+
Blather.logger.expects(val.to_sym).with("foo bar").once
|
28
|
+
Blather.default_log_level = val.to_sym
|
29
|
+
Blather.log "foo bar"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
def items_all_nodes_xml
|
2
|
+
<<-ITEMS
|
3
|
+
<iq type='result'
|
4
|
+
from='pubsub.shakespeare.lit'
|
5
|
+
to='francisco@denmark.lit/barracks'
|
6
|
+
id='items1'>
|
7
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
8
|
+
<items node='princely_musings'>
|
9
|
+
<item id='368866411b877c30064a5f62b917cffe'>
|
10
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
11
|
+
<title>The Uses of This World</title>
|
12
|
+
<summary>
|
13
|
+
O, that this too too solid flesh would melt
|
14
|
+
Thaw and resolve itself into a dew!
|
15
|
+
</summary>
|
16
|
+
<link rel='alternate' type='text/html'
|
17
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
18
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
19
|
+
<published>2003-12-12T17:47:23Z</published>
|
20
|
+
<updated>2003-12-12T17:47:23Z</updated>
|
21
|
+
</entry>
|
22
|
+
</item>
|
23
|
+
<item id='3300659945416e274474e469a1f0154c'>
|
24
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
25
|
+
<title>Ghostly Encounters</title>
|
26
|
+
<summary>
|
27
|
+
O all you host of heaven! O earth! what else?
|
28
|
+
And shall I couple hell? O, fie! Hold, hold, my heart;
|
29
|
+
And you, my sinews, grow not instant old,
|
30
|
+
But bear me stiffly up. Remember thee!
|
31
|
+
</summary>
|
32
|
+
<link rel='alternate' type='text/html'
|
33
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
34
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
35
|
+
<published>2003-12-12T23:21:34Z</published>
|
36
|
+
<updated>2003-12-12T23:21:34Z</updated>
|
37
|
+
</entry>
|
38
|
+
</item>
|
39
|
+
<item id='4e30f35051b7b8b42abe083742187228'>
|
40
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
41
|
+
<title>Alone</title>
|
42
|
+
<summary>
|
43
|
+
Now I am alone.
|
44
|
+
O, what a rogue and peasant slave am I!
|
45
|
+
</summary>
|
46
|
+
<link rel='alternate' type='text/html'
|
47
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
48
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
49
|
+
<published>2003-12-13T11:09:53Z</published>
|
50
|
+
<updated>2003-12-13T11:09:53Z</updated>
|
51
|
+
</entry>
|
52
|
+
</item>
|
53
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
|
54
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
55
|
+
<title>Soliloquy</title>
|
56
|
+
<summary>
|
57
|
+
To be, or not to be: that is the question:
|
58
|
+
Whether 'tis nobler in the mind to suffer
|
59
|
+
The slings and arrows of outrageous fortune,
|
60
|
+
Or to take arms against a sea of troubles,
|
61
|
+
And by opposing end them?
|
62
|
+
</summary>
|
63
|
+
<link rel='alternate' type='text/html'
|
64
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
65
|
+
<id>tag:denmark.lit,2003:entry-32397</id>
|
66
|
+
<published>2003-12-13T18:30:02Z</published>
|
67
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
68
|
+
</entry>
|
69
|
+
</item>
|
70
|
+
</items>
|
71
|
+
</pubsub>
|
72
|
+
</iq>
|
73
|
+
ITEMS
|
74
|
+
end
|
75
|
+
|
76
|
+
def pubsub_items_some_xml
|
77
|
+
<<-ITEMS
|
78
|
+
<iq type='result'
|
79
|
+
from='pubsub.shakespeare.lit'
|
80
|
+
to='francisco@denmark.lit/barracks'
|
81
|
+
id='items1'>
|
82
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
83
|
+
<items node='princely_musings'>
|
84
|
+
<item id='368866411b877c30064a5f62b917cffe'>
|
85
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
86
|
+
<title>The Uses of This World</title>
|
87
|
+
<summary>
|
88
|
+
O, that this too too solid flesh would melt
|
89
|
+
Thaw and resolve itself into a dew!
|
90
|
+
</summary>
|
91
|
+
<link rel='alternate' type='text/html'
|
92
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
93
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
94
|
+
<published>2003-12-12T17:47:23Z</published>
|
95
|
+
<updated>2003-12-12T17:47:23Z</updated>
|
96
|
+
</entry>
|
97
|
+
</item>
|
98
|
+
<item id='3300659945416e274474e469a1f0154c'>
|
99
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
100
|
+
<title>Ghostly Encounters</title>
|
101
|
+
<summary>
|
102
|
+
O all you host of heaven! O earth! what else?
|
103
|
+
And shall I couple hell? O, fie! Hold, hold, my heart;
|
104
|
+
And you, my sinews, grow not instant old,
|
105
|
+
But bear me stiffly up. Remember thee!
|
106
|
+
</summary>
|
107
|
+
<link rel='alternate' type='text/html'
|
108
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
109
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
110
|
+
<published>2003-12-12T23:21:34Z</published>
|
111
|
+
<updated>2003-12-12T23:21:34Z</updated>
|
112
|
+
</entry>
|
113
|
+
</item>
|
114
|
+
<item id='4e30f35051b7b8b42abe083742187228'>
|
115
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
116
|
+
<title>Alone</title>
|
117
|
+
<summary>
|
118
|
+
Now I am alone.
|
119
|
+
O, what a rogue and peasant slave am I!
|
120
|
+
</summary>
|
121
|
+
<link rel='alternate' type='text/html'
|
122
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
123
|
+
<id>tag:denmark.lit,2003:entry-32396</id>
|
124
|
+
<published>2003-12-13T11:09:53Z</published>
|
125
|
+
<updated>2003-12-13T11:09:53Z</updated>
|
126
|
+
</entry>
|
127
|
+
</item>
|
128
|
+
</items>
|
129
|
+
<set xmlns='http://jabber.org/protocol/rsm'>
|
130
|
+
<first index='0'>368866411b877c30064a5f62b917cffe</first>
|
131
|
+
<last>4e30f35051b7b8b42abe083742187228</last>
|
132
|
+
<count>19</count>
|
133
|
+
</set>
|
134
|
+
</pubsub>
|
135
|
+
</iq>
|
136
|
+
ITEMS
|
137
|
+
end
|
138
|
+
|
139
|
+
def affiliations_xml
|
140
|
+
<<-NODE
|
141
|
+
<iq type='result'
|
142
|
+
from='pubsub.shakespeare.lit'
|
143
|
+
to='francisco@denmark.lit'
|
144
|
+
id='affil1'>
|
145
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
146
|
+
<affiliations>
|
147
|
+
<affiliation node='node1' affiliation='owner'/>
|
148
|
+
<affiliation node='node2' affiliation='owner'/>
|
149
|
+
<affiliation node='node3' affiliation='publisher'/>
|
150
|
+
<affiliation node='node4' affiliation='outcast'/>
|
151
|
+
<affiliation node='node5' affiliation='member'/>
|
152
|
+
<affiliation node='node6' affiliation='none'/>
|
153
|
+
</affiliations>
|
154
|
+
</pubsub>
|
155
|
+
</iq>
|
156
|
+
NODE
|
157
|
+
end
|
158
|
+
|
159
|
+
def subscriptions_xml
|
160
|
+
<<-NODE
|
161
|
+
<iq type='result'
|
162
|
+
from='pubsub.shakespeare.lit'
|
163
|
+
to='francisco@denmark.lit'
|
164
|
+
id='affil1'>
|
165
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
166
|
+
<subscriptions>
|
167
|
+
<subscription node='node1' jid='francisco@denmark.lit' subscription='subscribed' subid='fd8237yr872h3f289j2'/>
|
168
|
+
<subscription node='node2' jid='francisco@denmark.lit' subscription='subscribed' subid='h8394hf8923ju'/>
|
169
|
+
<subscription node='node3' jid='francisco@denmark.lit' subscription='unconfigured'/>
|
170
|
+
<subscription node='node4' jid='francisco@denmark.lit' subscription='pending'/>
|
171
|
+
<subscription node='node5' jid='francisco@denmark.lit' subscription='none'/>
|
172
|
+
</subscriptions>
|
173
|
+
</pubsub>
|
174
|
+
</iq>
|
175
|
+
NODE
|
176
|
+
end
|
177
|
+
|
178
|
+
def event_with_payload_xml
|
179
|
+
<<-NODE
|
180
|
+
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
|
181
|
+
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
182
|
+
<items node='princely_musings'>
|
183
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
|
184
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
185
|
+
<title>Soliloquy</title>
|
186
|
+
<summary>
|
187
|
+
To be, or not to be: that is the question:
|
188
|
+
Whether 'tis nobler in the mind to suffer
|
189
|
+
The slings and arrows of outrageous fortune,
|
190
|
+
Or to take arms against a sea of troubles,
|
191
|
+
And by opposing end them?
|
192
|
+
</summary>
|
193
|
+
<link rel='alternate' type='text/html'
|
194
|
+
href='http://denmark.lit/2003/12/13/atom03'/>
|
195
|
+
<id>tag:denmark.lit,2003:entry-32397</id>
|
196
|
+
<published>2003-12-13T18:30:02Z</published>
|
197
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
198
|
+
</entry>
|
199
|
+
</item>
|
200
|
+
</items>
|
201
|
+
</event>
|
202
|
+
</message>
|
203
|
+
NODE
|
204
|
+
end
|
205
|
+
|
206
|
+
def event_notification_xml
|
207
|
+
<<-NODE
|
208
|
+
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
|
209
|
+
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
210
|
+
<items node='princely_musings'>
|
211
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'/>
|
212
|
+
</items>
|
213
|
+
</event>
|
214
|
+
</message>
|
215
|
+
NODE
|
216
|
+
end
|
217
|
+
|
218
|
+
def event_subids_xml
|
219
|
+
<<-NODE
|
220
|
+
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
|
221
|
+
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
222
|
+
<items node='princely_musings'>
|
223
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'/>
|
224
|
+
</items>
|
225
|
+
</event>
|
226
|
+
<headers xmlns='http://jabber.org/protocol/shim'>
|
227
|
+
<header name='SubID'>123-abc</header>
|
228
|
+
<header name='SubID'>004-yyy</header>
|
229
|
+
</headers>
|
230
|
+
</message>
|
231
|
+
NODE
|
232
|
+
end
|
233
|
+
|
234
|
+
def unsubscribe_xml
|
235
|
+
<<-NODE
|
236
|
+
<iq type='error'
|
237
|
+
from='pubsub.shakespeare.lit'
|
238
|
+
to='francisco@denmark.lit/barracks'
|
239
|
+
id='unsub1'>
|
240
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
241
|
+
<unsubscribe node='princely_musings' jid='francisco@denmark.lit'/>
|
242
|
+
</pubsub>
|
243
|
+
<error type='modify'>
|
244
|
+
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
245
|
+
<subid-required xmlns='http://jabber.org/protocol/pubsub#errors'/>
|
246
|
+
</error>
|
247
|
+
</iq>
|
248
|
+
NODE
|
249
|
+
end
|
250
|
+
|
251
|
+
def subscription_xml
|
252
|
+
<<-NODE
|
253
|
+
<iq type='result'
|
254
|
+
from='pubsub.shakespeare.lit'
|
255
|
+
to='francisco@denmark.lit/barracks'
|
256
|
+
id='sub1'>
|
257
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
258
|
+
<subscription
|
259
|
+
node='princely_musings'
|
260
|
+
jid='francisco@denmark.lit'
|
261
|
+
subid='ba49252aaa4f5d320c24d3766f0bdcade78c78d3'
|
262
|
+
subscription='subscribed'/>
|
263
|
+
</pubsub>
|
264
|
+
</iq>
|
265
|
+
NODE
|
266
|
+
end
|
267
|
+
|
268
|
+
def subscribe_xml
|
269
|
+
<<-NODE
|
270
|
+
<iq type='set'
|
271
|
+
from='francisco@denmark.lit/barracks'
|
272
|
+
to='pubsub.shakespeare.lit'
|
273
|
+
id='sub1'>
|
274
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
275
|
+
<subscribe
|
276
|
+
node='princely_musings'
|
277
|
+
jid='francisco@denmark.lit'/>
|
278
|
+
</pubsub>
|
279
|
+
</iq>
|
280
|
+
NODE
|
281
|
+
end
|
282
|
+
|
283
|
+
def publish_xml
|
284
|
+
<<-NODE
|
285
|
+
<iq type='result'
|
286
|
+
from='pubsub.shakespeare.lit'
|
287
|
+
to='hamlet@denmark.lit/blogbot'
|
288
|
+
id='publish1'>
|
289
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
290
|
+
<publish node='princely_musings'>
|
291
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'/>
|
292
|
+
</publish>
|
293
|
+
</pubsub>
|
294
|
+
</iq>
|
295
|
+
NODE
|
296
|
+
end
|
297
|
+
|
298
|
+
def retract_xml
|
299
|
+
<<-NODE
|
300
|
+
<iq type='set'
|
301
|
+
from='hamlet@denmark.lit/elsinore'
|
302
|
+
to='pubsub.shakespeare.lit'
|
303
|
+
id='retract1'>
|
304
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
305
|
+
<retract node='princely_musings'>
|
306
|
+
<item id='ae890ac52d0df67ed7cfdf51b644e901'/>
|
307
|
+
</retract>
|
308
|
+
</pubsub>
|
309
|
+
</iq>
|
310
|
+
NODE
|
311
|
+
end
|