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,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
|