tp-blather 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/.autotest +13 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +19 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +8 -0
  6. data/CHANGELOG.md +249 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +5 -0
  9. data/LICENSE +22 -0
  10. data/README.md +413 -0
  11. data/Rakefile +20 -0
  12. data/TODO.md +2 -0
  13. data/blather.gemspec +51 -0
  14. data/examples/certs/README +20 -0
  15. data/examples/certs/ca-bundle.crt +3987 -0
  16. data/examples/echo.rb +19 -0
  17. data/examples/execute.rb +17 -0
  18. data/examples/ping_pong.rb +38 -0
  19. data/examples/print_hierarchy.rb +77 -0
  20. data/examples/rosterprint.rb +15 -0
  21. data/examples/stream_only.rb +28 -0
  22. data/examples/trusted_echo.rb +21 -0
  23. data/examples/xmpp4r/echo.rb +36 -0
  24. data/lib/blather.rb +112 -0
  25. data/lib/blather/cert_store.rb +53 -0
  26. data/lib/blather/client.rb +95 -0
  27. data/lib/blather/client/client.rb +345 -0
  28. data/lib/blather/client/dsl.rb +320 -0
  29. data/lib/blather/client/dsl/pubsub.rb +174 -0
  30. data/lib/blather/core_ext/eventmachine.rb +125 -0
  31. data/lib/blather/core_ext/ipaddr.rb +20 -0
  32. data/lib/blather/errors.rb +69 -0
  33. data/lib/blather/errors/sasl_error.rb +44 -0
  34. data/lib/blather/errors/stanza_error.rb +110 -0
  35. data/lib/blather/errors/stream_error.rb +84 -0
  36. data/lib/blather/file_transfer.rb +107 -0
  37. data/lib/blather/file_transfer/ibb.rb +68 -0
  38. data/lib/blather/file_transfer/s5b.rb +114 -0
  39. data/lib/blather/jid.rb +141 -0
  40. data/lib/blather/roster.rb +118 -0
  41. data/lib/blather/roster_item.rb +146 -0
  42. data/lib/blather/stanza.rb +167 -0
  43. data/lib/blather/stanza/disco.rb +32 -0
  44. data/lib/blather/stanza/disco/capabilities.rb +161 -0
  45. data/lib/blather/stanza/disco/disco_info.rb +205 -0
  46. data/lib/blather/stanza/disco/disco_items.rb +134 -0
  47. data/lib/blather/stanza/iq.rb +144 -0
  48. data/lib/blather/stanza/iq/command.rb +339 -0
  49. data/lib/blather/stanza/iq/ibb.rb +86 -0
  50. data/lib/blather/stanza/iq/ping.rb +50 -0
  51. data/lib/blather/stanza/iq/query.rb +53 -0
  52. data/lib/blather/stanza/iq/roster.rb +185 -0
  53. data/lib/blather/stanza/iq/s5b.rb +208 -0
  54. data/lib/blather/stanza/iq/si.rb +415 -0
  55. data/lib/blather/stanza/iq/vcard.rb +149 -0
  56. data/lib/blather/stanza/message.rb +428 -0
  57. data/lib/blather/stanza/message/muc_user.rb +119 -0
  58. data/lib/blather/stanza/muc/muc_user_base.rb +54 -0
  59. data/lib/blather/stanza/presence.rb +172 -0
  60. data/lib/blather/stanza/presence/c.rb +100 -0
  61. data/lib/blather/stanza/presence/muc.rb +35 -0
  62. data/lib/blather/stanza/presence/muc_user.rb +147 -0
  63. data/lib/blather/stanza/presence/status.rb +218 -0
  64. data/lib/blather/stanza/presence/subscription.rb +100 -0
  65. data/lib/blather/stanza/pubsub.rb +119 -0
  66. data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
  67. data/lib/blather/stanza/pubsub/create.rb +65 -0
  68. data/lib/blather/stanza/pubsub/errors.rb +18 -0
  69. data/lib/blather/stanza/pubsub/event.rb +139 -0
  70. data/lib/blather/stanza/pubsub/items.rb +103 -0
  71. data/lib/blather/stanza/pubsub/publish.rb +103 -0
  72. data/lib/blather/stanza/pubsub/retract.rb +92 -0
  73. data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
  74. data/lib/blather/stanza/pubsub/subscription.rb +135 -0
  75. data/lib/blather/stanza/pubsub/subscriptions.rb +83 -0
  76. data/lib/blather/stanza/pubsub/unsubscribe.rb +84 -0
  77. data/lib/blather/stanza/pubsub_owner.rb +51 -0
  78. data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
  79. data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
  80. data/lib/blather/stanza/x.rb +416 -0
  81. data/lib/blather/stream.rb +266 -0
  82. data/lib/blather/stream/client.rb +32 -0
  83. data/lib/blather/stream/component.rb +39 -0
  84. data/lib/blather/stream/features.rb +70 -0
  85. data/lib/blather/stream/features/register.rb +38 -0
  86. data/lib/blather/stream/features/resource.rb +63 -0
  87. data/lib/blather/stream/features/sasl.rb +190 -0
  88. data/lib/blather/stream/features/session.rb +45 -0
  89. data/lib/blather/stream/features/tls.rb +29 -0
  90. data/lib/blather/stream/parser.rb +102 -0
  91. data/lib/blather/version.rb +3 -0
  92. data/lib/blather/xmpp_node.rb +94 -0
  93. data/spec/blather/client/client_spec.rb +687 -0
  94. data/spec/blather/client/dsl/pubsub_spec.rb +492 -0
  95. data/spec/blather/client/dsl_spec.rb +266 -0
  96. data/spec/blather/errors/sasl_error_spec.rb +33 -0
  97. data/spec/blather/errors/stanza_error_spec.rb +129 -0
  98. data/spec/blather/errors/stream_error_spec.rb +108 -0
  99. data/spec/blather/errors_spec.rb +33 -0
  100. data/spec/blather/file_transfer_spec.rb +135 -0
  101. data/spec/blather/jid_spec.rb +87 -0
  102. data/spec/blather/roster_item_spec.rb +134 -0
  103. data/spec/blather/roster_spec.rb +107 -0
  104. data/spec/blather/stanza/discos/disco_info_spec.rb +247 -0
  105. data/spec/blather/stanza/discos/disco_items_spec.rb +154 -0
  106. data/spec/blather/stanza/iq/command_spec.rb +206 -0
  107. data/spec/blather/stanza/iq/ibb_spec.rb +124 -0
  108. data/spec/blather/stanza/iq/ping_spec.rb +45 -0
  109. data/spec/blather/stanza/iq/query_spec.rb +64 -0
  110. data/spec/blather/stanza/iq/roster_spec.rb +139 -0
  111. data/spec/blather/stanza/iq/s5b_spec.rb +57 -0
  112. data/spec/blather/stanza/iq/si_spec.rb +98 -0
  113. data/spec/blather/stanza/iq/vcard_spec.rb +93 -0
  114. data/spec/blather/stanza/iq_spec.rb +61 -0
  115. data/spec/blather/stanza/message/muc_user_spec.rb +152 -0
  116. data/spec/blather/stanza/message_spec.rb +282 -0
  117. data/spec/blather/stanza/presence/c_spec.rb +56 -0
  118. data/spec/blather/stanza/presence/muc_spec.rb +37 -0
  119. data/spec/blather/stanza/presence/muc_user_spec.rb +83 -0
  120. data/spec/blather/stanza/presence/status_spec.rb +144 -0
  121. data/spec/blather/stanza/presence/subscription_spec.rb +102 -0
  122. data/spec/blather/stanza/presence_spec.rb +125 -0
  123. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  124. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  125. data/spec/blather/stanza/pubsub/event_spec.rb +98 -0
  126. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  127. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  128. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  129. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  130. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  131. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  132. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +74 -0
  133. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  134. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  135. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  136. data/spec/blather/stanza/pubsub_spec.rb +68 -0
  137. data/spec/blather/stanza/x_spec.rb +231 -0
  138. data/spec/blather/stanza_spec.rb +134 -0
  139. data/spec/blather/stream/client_spec.rb +1090 -0
  140. data/spec/blather/stream/component_spec.rb +108 -0
  141. data/spec/blather/stream/parser_spec.rb +152 -0
  142. data/spec/blather/stream/ssl_spec.rb +32 -0
  143. data/spec/blather/xmpp_node_spec.rb +47 -0
  144. data/spec/blather_spec.rb +34 -0
  145. data/spec/fixtures/pubsub.rb +311 -0
  146. data/spec/spec_helper.rb +17 -0
  147. data/yard/templates/default/class/html/handlers.erb +18 -0
  148. data/yard/templates/default/class/setup.rb +10 -0
  149. data/yard/templates/default/class/text/handlers.erb +1 -0
  150. 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&amp;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