vines 0.4.5 → 0.4.6

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