vines 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +48 -0
  3. data/Rakefile +6 -58
  4. data/bin/vines +12 -2
  5. data/conf/certs/ca-bundle.crt +568 -39
  6. data/conf/config.rb +9 -42
  7. data/lib/vines.rb +1 -8
  8. data/lib/vines/command/cert.rb +4 -4
  9. data/lib/vines/command/init.rb +3 -3
  10. data/lib/vines/config.rb +9 -0
  11. data/lib/vines/kit.rb +2 -7
  12. data/lib/vines/storage/local.rb +50 -17
  13. data/lib/vines/store.rb +6 -4
  14. data/lib/vines/stream.rb +1 -1
  15. data/lib/vines/stream/http/session.rb +0 -0
  16. data/lib/vines/stream/http/sessions.rb +0 -0
  17. data/lib/vines/stream/parser.rb +3 -2
  18. data/lib/vines/token_bucket.rb +19 -10
  19. data/lib/vines/version.rb +1 -1
  20. data/test/cluster/publisher_test.rb +45 -33
  21. data/test/cluster/sessions_test.rb +32 -39
  22. data/test/cluster/subscriber_test.rb +93 -78
  23. data/test/config/host_test.rb +2 -4
  24. data/test/config/pubsub_test.rb +132 -126
  25. data/test/config_test.rb +2 -4
  26. data/test/contact_test.rb +80 -66
  27. data/test/error_test.rb +54 -55
  28. data/test/jid_test.rb +1 -2
  29. data/test/kit_test.rb +22 -17
  30. data/test/router_test.rb +187 -146
  31. data/test/stanza/iq/disco_info_test.rb +59 -59
  32. data/test/stanza/iq/disco_items_test.rb +36 -34
  33. data/test/stanza/iq/private_storage_test.rb +138 -143
  34. data/test/stanza/iq/roster_test.rb +198 -175
  35. data/test/stanza/iq/session_test.rb +17 -18
  36. data/test/stanza/iq/vcard_test.rb +117 -116
  37. data/test/stanza/iq/version_test.rb +47 -46
  38. data/test/stanza/iq_test.rb +53 -49
  39. data/test/stanza/message_test.rb +92 -89
  40. data/test/stanza/presence/probe_test.rb +2 -5
  41. data/test/stanza/presence/subscribe_test.rb +67 -54
  42. data/test/stanza/pubsub/create_test.rb +86 -108
  43. data/test/stanza/pubsub/delete_test.rb +141 -114
  44. data/test/stanza/pubsub/publish_test.rb +256 -320
  45. data/test/stanza/pubsub/subscribe_test.rb +169 -150
  46. data/test/stanza/pubsub/unsubscribe_test.rb +111 -142
  47. data/test/stanza_test.rb +61 -54
  48. data/test/storage/ldap_test.rb +1 -2
  49. data/test/storage/local_test.rb +3 -5
  50. data/test/storage/null_test.rb +3 -4
  51. data/test/storage/storage_tests.rb +1 -3
  52. data/test/storage_test.rb +1 -2
  53. data/test/store_test.rb +1 -2
  54. data/test/stream/client/auth_test.rb +61 -63
  55. data/test/stream/client/ready_test.rb +7 -8
  56. data/test/stream/client/session_test.rb +19 -18
  57. data/test/stream/component/handshake_test.rb +40 -37
  58. data/test/stream/component/ready_test.rb +76 -61
  59. data/test/stream/component/start_test.rb +7 -8
  60. data/test/stream/http/auth_test.rb +3 -4
  61. data/test/stream/http/ready_test.rb +52 -60
  62. data/test/stream/http/request_test.rb +1 -3
  63. data/test/stream/http/sessions_test.rb +2 -3
  64. data/test/stream/http/start_test.rb +3 -4
  65. data/test/stream/parser_test.rb +3 -4
  66. data/test/stream/sasl_test.rb +105 -86
  67. data/test/stream/server/auth_test.rb +40 -36
  68. data/test/stream/server/outbound/auth_test.rb +3 -4
  69. data/test/stream/server/ready_test.rb +51 -51
  70. data/test/test_helper.rb +42 -0
  71. data/test/token_bucket_test.rb +38 -18
  72. data/test/user_test.rb +79 -49
  73. data/vines.gemspec +33 -0
  74. data/web/chat/javascripts/app.js +1 -1
  75. data/web/lib/coffeescripts/layout.coffee +1 -1
  76. data/web/lib/javascripts/base.js +10 -10
  77. data/web/lib/javascripts/jquery.js +4 -4
  78. metadata +31 -128
  79. data/README +0 -35
  80. data/lib/vines/storage/couchdb.rb +0 -129
  81. data/lib/vines/storage/mongodb.rb +0 -132
  82. data/lib/vines/storage/redis.rb +0 -127
  83. data/lib/vines/storage/sql.rb +0 -220
  84. data/test/rake_test_loader.rb +0 -17
  85. data/test/storage/couchdb_test.rb +0 -107
  86. data/test/storage/mock_mongo.rb +0 -40
  87. data/test/storage/mongodb_test.rb +0 -81
  88. data/test/storage/redis_test.rb +0 -51
  89. data/test/storage/sql_test.rb +0 -62
@@ -1,63 +1,64 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class VersionTest < MiniTest::Unit::TestCase
9
- def setup
10
- @stream = MiniTest::Mock.new
11
- @config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::Iq::Version do
6
+ subject { Vines::Stanza::Iq::Version.new(xml, stream) }
7
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
8
+ let(:stream) { MiniTest::Mock.new }
9
+ let(:config) do
10
+ Vines::Config.new do
12
11
  host 'wonderland.lit' do
13
12
  storage(:fs) { dir Dir.tmpdir }
14
13
  end
15
14
  end
16
15
  end
17
16
 
18
- def test_to_address_routes
19
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
20
- node = node(%q{<iq id="42" to="romeo@verona.lit" type="get"><query xmlns="jabber:iq:version"/></iq>})
21
-
22
- router = MiniTest::Mock.new
23
- router.expect(:route, nil, [node])
24
-
25
- @stream.expect(:config, @config)
26
- @stream.expect(:user, alice)
27
- @stream.expect(:router, router)
28
-
29
- stanza = Vines::Stanza::Iq::Version.new(node, @stream)
30
- stanza.process
31
- assert @stream.verify
32
- assert router.verify
17
+ before do
18
+ class << stream
19
+ attr_accessor :config, :user
20
+ end
21
+ stream.config = config
22
+ stream.user = alice
33
23
  end
34
24
 
35
- def test_version_get_returns_result
36
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
37
- node = node(%q{<iq id="42" type="get"><query xmlns="jabber:iq:version"/></iq>})
38
-
39
- @stream.expect(:config, @config)
40
- @stream.expect(:user, alice)
41
- @stream.expect(:domain, 'wonderland.lit')
42
-
43
- expected = node(%Q{
44
- <iq from="wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
45
- <query xmlns="jabber:iq:version">
46
- <name>Vines</name>
47
- <version>#{Vines::VERSION}</version>
48
- </query>
49
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
25
+ describe 'when not addressed to the server' do
26
+ let(:router) { MiniTest::Mock.new }
27
+ let(:xml) { node(%q{<iq id="42" to="romeo@verona.lit" type="get"><query xmlns="jabber:iq:version"/></iq>}) }
50
28
 
51
- @stream.expect(:write, nil, [expected])
29
+ before do
30
+ router.expect :route, nil, [xml]
31
+ stream.expect :router, router
32
+ end
52
33
 
53
- stanza = Vines::Stanza::Iq::Version.new(node, @stream)
54
- stanza.process
55
- assert @stream.verify
34
+ it 'routes the stanza to the recipient jid' do
35
+ subject.process
36
+ stream.verify
37
+ router.verify
38
+ end
56
39
  end
57
40
 
58
- private
41
+ describe 'when missing a to address' do
42
+ let(:xml) { node(%q{<iq id="42" type="get"><query xmlns="jabber:iq:version"/></iq>}) }
43
+ let(:expected) do
44
+ node(%Q{
45
+ <iq from="wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
46
+ <query xmlns="jabber:iq:version">
47
+ <name>Vines</name>
48
+ <version>#{Vines::VERSION}</version>
49
+ </query>
50
+ </iq>})
51
+ end
52
+
53
+ before do
54
+ stream.expect :domain, 'wonderland.lit'
55
+ stream.expect :domain, 'wonderland.lit'
56
+ stream.expect :write, nil, [expected]
57
+ end
59
58
 
60
- def node(xml)
61
- Nokogiri::XML(xml).root
59
+ it 'returns a version result when missing a to jid' do
60
+ subject.process
61
+ stream.verify
62
+ end
62
63
  end
63
64
  end
@@ -1,66 +1,70 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
3
+ require 'test_helper'
7
4
 
8
- class IqTest < MiniTest::Unit::TestCase
9
- def setup
10
- @stream = MiniTest::Mock.new
11
- @config = Vines::Config.new do
5
+ describe Vines::Stanza::Iq do
6
+ subject { Vines::Stanza::Iq.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
9
+ let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit/crumpets') }
10
+ let(:config) do
11
+ Vines::Config.new do
12
12
  host 'wonderland.lit' do
13
13
  storage(:fs) { dir Dir.tmpdir }
14
14
  end
15
15
  end
16
16
  end
17
17
 
18
- def test_allow_other_iq_to_route
19
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
20
- hatter = Vines::User.new(:jid => 'hatter@wonderland.lit/crumpets')
21
- node = node(%q{
22
- <iq id="42" type="set" to="alice@wonderland.lit/tea" from="hatter@wonderland.lit/crumpets">
23
- <si xmlns="http://jabber.org/protocol/si" id="42_si" profile="http://jabber.org/protocol/si/profile/file-transfer">
24
- <file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="file" size="1"/>
25
- <feature xmlns="http://jabber.org/protocol/feature-neg">
26
- <x xmlns="jabber:x:data" type="form">
27
- <field var="stream-method" type="list-single">
28
- <option>
29
- <value>http://jabber.org/protocol/bytestreams</value>
30
- </option>
31
- <option>
32
- <value>http://jabber.org/protocol/ibb</value>
33
- </option>
34
- </field>
35
- </x>
36
- </feature>
37
- </si>
38
- </iq>
39
- }.strip.gsub(/\n|\s{2,}/, ''))
40
-
41
- recipient = MiniTest::Mock.new
42
- recipient.expect(:user, alice, [])
43
- recipient.expect(:write, nil, [node])
18
+ before do
19
+ class << stream
20
+ attr_accessor :config, :user
21
+ end
22
+ stream.user = hatter
23
+ stream.config = config
24
+ end
44
25
 
45
- @stream.expect(:config, @config)
46
- @stream.expect(:user, hatter)
47
- @stream.expect(:connected_resources, [recipient], [alice.jid])
26
+ describe 'when addressed to a user rather than the server itself' do
27
+ let(:recipient) { MiniTest::Mock.new }
28
+ let(:xml) do
29
+ node(%q{
30
+ <iq id="42" type="set" to="alice@wonderland.lit/tea" from="hatter@wonderland.lit/crumpets">
31
+ <si xmlns="http://jabber.org/protocol/si" id="42_si" profile="http://jabber.org/protocol/si/profile/file-transfer">
32
+ <file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="file" size="1"/>
33
+ <feature xmlns="http://jabber.org/protocol/feature-neg">
34
+ <x xmlns="jabber:x:data" type="form">
35
+ <field var="stream-method" type="list-single">
36
+ <option>
37
+ <value>http://jabber.org/protocol/bytestreams</value>
38
+ </option>
39
+ <option>
40
+ <value>http://jabber.org/protocol/ibb</value>
41
+ </option>
42
+ </field>
43
+ </x>
44
+ </feature>
45
+ </si>
46
+ </iq>
47
+ })
48
+ end
48
49
 
49
- stanza = Vines::Stanza::Iq.new(node, @stream)
50
- stanza.process
51
- assert @stream.verify
52
- assert recipient.verify
53
- end
50
+ before do
51
+ recipient.expect :user, alice, []
52
+ recipient.expect :write, nil, [xml]
53
+ stream.expect :connected_resources, [recipient], [alice.jid]
54
+ end
54
55
 
55
- def test_feature_not_implemented
56
- node = node('<iq type="set" id="42"/>')
57
- stanza = Vines::Stanza::Iq.new(node, @stream)
58
- assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
56
+ it 'routes the stanza to the users connected resources' do
57
+ subject.process
58
+ stream.verify
59
+ recipient.verify
60
+ end
59
61
  end
60
62
 
61
- private
63
+ describe 'when given no type or body elements' do
64
+ let(:xml) { node('<iq type="set" id="42"/>') }
62
65
 
63
- def node(xml)
64
- Nokogiri::XML(xml).root
66
+ it 'raises a feature-not-implemented stanza error' do
67
+ -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented
68
+ end
65
69
  end
66
70
  end
@@ -1,123 +1,126 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class MessageTest < MiniTest::Unit::TestCase
9
- def setup
10
- @stream = MiniTest::Mock.new
11
- @config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::Message do
6
+ subject { Vines::Stanza::Message.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
9
+ let(:romeo) { Vines::User.new(jid: 'romeo@verona.lit/balcony') }
10
+ let(:config) do
11
+ Vines::Config.new do
12
12
  host 'wonderland.lit' do
13
13
  storage(:fs) { dir Dir.tmpdir }
14
14
  end
15
15
  end
16
16
  end
17
17
 
18
- def test_bad_type_returns_error
19
- node = node('<message type="bogus">hello!</message>')
20
- stanza = Vines::Stanza::Message.new(node, @stream)
21
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
18
+ before do
19
+ class << stream
20
+ attr_accessor :config, :user
21
+ end
22
+ stream.user = alice
23
+ stream.config = config
22
24
  end
23
25
 
24
- def test_missing_to_address_is_sent_to_sender
25
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
26
- node = node('<message>hello!</message>')
27
-
28
- recipient = MiniTest::Mock.new
29
- recipient.expect(:user, alice)
30
- recipient.expect(:write, nil, [node])
31
-
32
- @stream.expect(:user, alice)
33
- @stream.expect(:connected_resources, [recipient], [alice.jid.bare])
26
+ describe 'when message type attribute is invalid' do
27
+ let(:xml) { node('<message type="bogus">hello!</message>') }
34
28
 
35
- stanza = Vines::Stanza::Message.new(node, @stream)
36
- stanza.process
37
- assert @stream.verify
38
- assert recipient.verify
29
+ it 'raises a bad-request stanza error' do
30
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
31
+ end
39
32
  end
40
33
 
41
- def test_message_to_non_user_is_ignored
42
- bogus = Vines::JID.new('bogus@wonderland.lit/cake')
43
- node = node(%Q{<message to="#{bogus}">hello!</message>})
44
-
45
- storage = MiniTest::Mock.new
46
- storage.expect(:find_user, nil, [bogus])
34
+ describe 'when the to address is missing' do
35
+ let(:xml) { node('<message>hello!</message>') }
36
+ let(:recipient) { MiniTest::Mock.new }
47
37
 
48
- @stream.expect(:config, @config)
49
- @stream.expect(:storage, storage, [bogus.domain])
50
- @stream.expect(:connected_resources, [], [bogus])
38
+ before do
39
+ recipient.expect :user, alice
40
+ recipient.expect :write, nil, [xml]
41
+ stream.expect :connected_resources, [recipient], [alice.jid.bare]
42
+ end
51
43
 
52
- stanza = Vines::Stanza::Message.new(node, @stream)
53
- stanza.process
54
- assert @stream.verify
55
- assert storage.verify
44
+ it 'sends the message to the senders connected streams' do
45
+ subject.process
46
+ stream.verify
47
+ recipient.verify
48
+ end
56
49
  end
57
50
 
58
- def test_message_to_offline_user_returns_error
59
- hatter = Vines::User.new(:jid => 'hatter@wonderland.lit/cake')
60
- node = node(%Q{<message to="#{hatter.jid}">hello!</message>})
61
-
62
- storage = MiniTest::Mock.new
63
- storage.expect(:find_user, hatter, [hatter.jid])
51
+ describe 'when addressed to a non-user' do
52
+ let(:bogus) { Vines::JID.new('bogus@wonderland.lit/cake') }
53
+ let(:xml) { node(%Q{<message to="#{bogus}">hello!</message>}) }
54
+ let(:storage) { MiniTest::Mock.new }
64
55
 
65
- @stream.expect(:config, @config)
66
- @stream.expect(:storage, storage, [hatter.jid.domain])
67
- @stream.expect(:connected_resources, [], [hatter.jid])
56
+ before do
57
+ storage.expect :find_user, nil, [bogus]
58
+ stream.expect :storage, storage, [bogus.domain]
59
+ stream.expect :connected_resources, [], [bogus]
60
+ end
68
61
 
69
- stanza = Vines::Stanza::Message.new(node, @stream)
70
- assert_raises(Vines::StanzaErrors::ServiceUnavailable) { stanza.process }
71
- assert @stream.verify
72
- assert storage.verify
62
+ it 'ignores the stanza' do
63
+ subject.process
64
+ stream.verify
65
+ storage.verify
66
+ end
73
67
  end
74
68
 
75
- def test_message_to_local_user_in_different_domain_is_delivered
76
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
77
- romeo = Vines::User.new(:jid => 'romeo@verona.lit/balcony')
78
- node = node(%Q{<message to="#{romeo.jid}">hello!</message>})
79
- expected = node(%Q{<message to="#{romeo.jid}" from="#{alice.jid}">hello!</message>})
80
-
81
- recipient = MiniTest::Mock.new
82
- recipient.expect(:user, romeo)
83
- recipient.expect(:write, nil, [expected])
69
+ describe 'when addressed to an offline user' do
70
+ let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit/cake') }
71
+ let(:xml) { node(%Q{<message to="#{hatter.jid}">hello!</message>}) }
72
+ let(:storage) { MiniTest::Mock.new }
84
73
 
85
- @config.host 'verona.lit' do
86
- storage(:fs) { dir Dir.tmpdir }
74
+ before do
75
+ storage.expect :find_user, hatter, [hatter.jid]
76
+ stream.expect :storage, storage, [hatter.jid.domain]
77
+ stream.expect :connected_resources, [], [hatter.jid]
87
78
  end
88
79
 
89
- @stream.expect(:config, @config)
90
- @stream.expect(:user, alice)
91
- @stream.expect(:connected_resources, [recipient], [romeo.jid])
92
-
93
- stanza = Vines::Stanza::Message.new(node, @stream)
94
- stanza.process
95
- assert @stream.verify
96
- assert recipient.verify
80
+ it 'raises a service-unavailable stanza error' do
81
+ -> { subject.process }.must_raise Vines::StanzaErrors::ServiceUnavailable
82
+ stream.verify
83
+ storage.verify
84
+ end
97
85
  end
98
86
 
99
- def test_message_to_remote_user_is_routed
100
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
101
- romeo = Vines::User.new(:jid => 'romeo@verona.lit/balcony')
102
- node = node(%Q{<message to="#{romeo.jid}">hello!</message>})
103
- expected = node(%Q{<message to="#{romeo.jid}" from="#{alice.jid}">hello!</message>})
87
+ describe 'when address to a local user in a different domain' do
88
+ let(:xml) { node(%Q{<message to="#{romeo.jid}">hello!</message>}) }
89
+ let(:expected) { node(%Q{<message to="#{romeo.jid}" from="#{alice.jid}">hello!</message>}) }
90
+ let(:recipient) { MiniTest::Mock.new }
91
+
92
+ before do
93
+ recipient.expect :user, romeo
94
+ recipient.expect :write, nil, [expected]
104
95
 
105
- router = MiniTest::Mock.new
106
- @stream.expect(:config, @config)
107
- router.expect(:route, nil, [expected])
96
+ config.host 'verona.lit' do
97
+ storage(:fs) { dir Dir.tmpdir }
98
+ end
108
99
 
109
- @stream.expect(:router, router)
110
- @stream.expect(:user, alice)
100
+ stream.expect :connected_resources, [recipient], [romeo.jid]
101
+ end
111
102
 
112
- stanza = Vines::Stanza::Message.new(node, @stream)
113
- stanza.process
114
- assert @stream.verify
115
- assert router.verify
103
+ it 'delivers the stanza to the user' do
104
+ subject.process
105
+ stream.verify
106
+ recipient.verify
107
+ end
116
108
  end
117
109
 
118
- private
110
+ describe 'when addressed to a remote user' do
111
+ let(:xml) { node(%Q{<message to="#{romeo.jid}">hello!</message>}) }
112
+ let(:expected) { node(%Q{<message to="#{romeo.jid}" from="#{alice.jid}">hello!</message>}) }
113
+ let(:router) { MiniTest::Mock.new }
119
114
 
120
- def node(xml)
121
- Nokogiri::XML(xml).root
115
+ before do
116
+ router.expect :route, nil, [expected]
117
+ stream.expect :router, router
118
+ end
119
+
120
+ it 'routes rather than handle locally' do
121
+ subject.process
122
+ stream.verify
123
+ router.verify
124
+ end
122
125
  end
123
126
  end
@@ -1,11 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
3
+ require 'test_helper'
7
4
 
8
- class ProbeTest < MiniTest::Unit::TestCase
5
+ describe Vines::Stanza::Presence::Probe do
9
6
  def setup
10
7
  @alice = Vines::JID.new('alice@wonderland.lit/tea')
11
8
  @stream = MiniTest::Mock.new